I need to pass an array from VBScript to VB.Net COM .DLL
-
I would need to pass an array (variant) which was dimensioned and "filled" in VBScript to a com-interop-based VB.Net .dll On the VBS side I got;
Dim DoubleArray(4) 'Fixed size array
DoubleArray(0) = 100
DoubleArray(1) = 200
DoubleArray(2) = 300
DoubleArray(3) = 400This is purely for test purposes so don't lose it over the inefficiency of the way I did that ;) On the VB.net dll side I got the following property with which I tried to get the array;
Public Property DataY() As Object()
Get
Return RezultatiY
End Get
Set(ByVal value As Object())
RezultatiY = value
End SetEnd Property
At first I tried declaring DataY as Integer Array and got "type mismatch" error, this was before I was aware of the fact that VBS does not deal with "type" arrays (integer array, string array), only "variant" ones. This made me try to pass it as an object...again it didn't work. I have never before worked with VBScript (which is painfully apparent) and after having spent 2 days pouring over google search results it became self evident that the problem is not only in my lack of knowledge but also in some sort of inconsistency between array definitions in VB.Net and VBScript. Currently I am fiddling with the following method in my COM .dll, hoping it would work;
Public Class GetArray
Public Function GetArrayPls(ByRef vntArray As VariantType)
Dim NewArray = Nothing
NewArray = vntArray
MsgBox(vntArray(1).ToString)
Return NewArray
End Function*Any* help would be *much* appreciated. Thanks!
-
I would need to pass an array (variant) which was dimensioned and "filled" in VBScript to a com-interop-based VB.Net .dll On the VBS side I got;
Dim DoubleArray(4) 'Fixed size array
DoubleArray(0) = 100
DoubleArray(1) = 200
DoubleArray(2) = 300
DoubleArray(3) = 400This is purely for test purposes so don't lose it over the inefficiency of the way I did that ;) On the VB.net dll side I got the following property with which I tried to get the array;
Public Property DataY() As Object()
Get
Return RezultatiY
End Get
Set(ByVal value As Object())
RezultatiY = value
End SetEnd Property
At first I tried declaring DataY as Integer Array and got "type mismatch" error, this was before I was aware of the fact that VBS does not deal with "type" arrays (integer array, string array), only "variant" ones. This made me try to pass it as an object...again it didn't work. I have never before worked with VBScript (which is painfully apparent) and after having spent 2 days pouring over google search results it became self evident that the problem is not only in my lack of knowledge but also in some sort of inconsistency between array definitions in VB.Net and VBScript. Currently I am fiddling with the following method in my COM .dll, hoping it would work;
Public Class GetArray
Public Function GetArrayPls(ByRef vntArray As VariantType)
Dim NewArray = Nothing
NewArray = vntArray
MsgBox(vntArray(1).ToString)
Return NewArray
End Function*Any* help would be *much* appreciated. Thanks!
-
Indeed, now I know even less than I did before LOL. Progress report; I have managed to send a simple string from VBS to NET which I can then easily delimit and fill an array with delimited elements all under .net This works but its not what I wanted, and I get annoyed when I feel too stupid to figure something out, it gets personal at that point ;) I am therefore still trying to get an array across, the latest fail in the (long) row being;
Microsoft VBScript runtime error '800a01ca' Variable uses an Automation type not supported in VBScript: 'Method3' /test2.asp, line 21
Maybe I could do a "byref" to circumvent this but I don't want to use "byref". In the meantime I have tried using "byref" just to see whether it would work, it did.<% @Language="VBScript" %>
<% Option Explicit %>
<%Dim rc
dim cta
dim arrayz(5)
arrayz(0) = 100
arrayz(1) = 200
arrayz(2) = 300
arrayz(3) = 400
arrayz(4) = 500set cta = Server.CreateObject("APP.APPCLASS")
rc = cta.METHOD((arrayz))%>
And the method being;
Public Function METHOD(ByRef arrayz) As Boolean
My.Computer.FileSystem.WriteAllText("C:\Temp\test3.txt", arrayz(2).ToString, True)
End FunctionThis gave a "300" in my text file. I hate using "byref" so I would still welcome another approach to the problem. I have also been studying the example being given here: http://www.15seconds.com/Issue/990826.htm[^] I was able to reproduce what the author did, but he basically gave a string "a,b,c,d", then he delimited it under net and made a new array, filled it with a,b,c and then byref exported the net array to VBScript, this is still not what I need. I simply cant believe that there is no normal and logical way of passing an array from VBS to .Net
-
Indeed, now I know even less than I did before LOL. Progress report; I have managed to send a simple string from VBS to NET which I can then easily delimit and fill an array with delimited elements all under .net This works but its not what I wanted, and I get annoyed when I feel too stupid to figure something out, it gets personal at that point ;) I am therefore still trying to get an array across, the latest fail in the (long) row being;
Microsoft VBScript runtime error '800a01ca' Variable uses an Automation type not supported in VBScript: 'Method3' /test2.asp, line 21
Maybe I could do a "byref" to circumvent this but I don't want to use "byref". In the meantime I have tried using "byref" just to see whether it would work, it did.<% @Language="VBScript" %>
<% Option Explicit %>
<%Dim rc
dim cta
dim arrayz(5)
arrayz(0) = 100
arrayz(1) = 200
arrayz(2) = 300
arrayz(3) = 400
arrayz(4) = 500set cta = Server.CreateObject("APP.APPCLASS")
rc = cta.METHOD((arrayz))%>
And the method being;
Public Function METHOD(ByRef arrayz) As Boolean
My.Computer.FileSystem.WriteAllText("C:\Temp\test3.txt", arrayz(2).ToString, True)
End FunctionThis gave a "300" in my text file. I hate using "byref" so I would still welcome another approach to the problem. I have also been studying the example being given here: http://www.15seconds.com/Issue/990826.htm[^] I was able to reproduce what the author did, but he basically gave a string "a,b,c,d", then he delimited it under net and made a new array, filled it with a,b,c and then byref exported the net array to VBScript, this is still not what I need. I simply cant believe that there is no normal and logical way of passing an array from VBS to .Net
-
hi Hrizip, I ran into similar situation as you. and I would like to know what the meaning of the syntax of bracketing around the array variable? rc = cta.METHOD((arrayz)) thanks!
The UI should look beautiful, so do the coding
Double bracketing is not necessary, its just that I read *somewhere* that it does something, but at this point I dont remember what, and I remember that the thing works just fine with single bracketing. Heres a code snippet to play with; So, make a new project of type class library, make it com visible and interoperable Paste this
Imports System.IO
Imports System.Math
Imports System.Object
Imports System.Threading
Imports System.Runtime.InteropServices
Imports System.Reflection
Imports System.Runtime.CompilerServices
Imports System.Runtime.InteropServices.RegistrationServices
Imports System.Xml
Imports System.Xml.XPathPublic Class Class1 ' Main Class, declared as *com interopable*, type of project : "type library", meaning it will need to be registered in windows, and type library will need to be exported
' you wlll need to make a batch file with the following commands in it, to check whether it has been introduced into the global assembly cache, browse your hard drive
' to windows/assembly and look for an entry named "Test", if it *is* listed there, then it will work.'regasm Test.dll 'regasm Test.dll /tlb:Test.dll 'regasm Test.dll /codebase /tlb:Test.dll 'gacutil /i Test.dll ' Put it into the folder where you already put test.dll, along with \*regasm.exe\* and \*gacutil.exe\* (obligatory) and then execute the bat file ' The type library is now registered and you can call its methods (the only working method is called "Method1") Public Shared RezultatiY ' vb.NET array to hold our data Public Function MethodNumber(ByRef numberz) ' Fetch the array of type integer or double (will be converted to double) RezultatiY = Nothing Dim Arrayzz() As Object Arrayzz = Nothing Arrayzz = numberz Dim NumberOfElements As Integer = UBound(numberz) - 1 ' We need to find the total number of elements ReDim RezultatiY(NumberOfElements) ' And then redimension our array to that number of elements For i As Integer = 0 To UBound(Arrayzz) - 1 Dim Temp As Double = CDbl(Arrayzz(i)) RezultatiY(i) = CDbl(Temp) My.Computer.FileSystem.WriteAllText("C:\\Temp\\TestingIntegersAndDoubles.txt", RezultatiY(i) & " " & i & " " & " " & RezultatiY(i).GetType.ToString & vbCrLf, True) Next End Function Public Function MethodString(ByRef Words) ' Fetch the array of type string RezultatiY = Nothing
-
Double bracketing is not necessary, its just that I read *somewhere* that it does something, but at this point I dont remember what, and I remember that the thing works just fine with single bracketing. Heres a code snippet to play with; So, make a new project of type class library, make it com visible and interoperable Paste this
Imports System.IO
Imports System.Math
Imports System.Object
Imports System.Threading
Imports System.Runtime.InteropServices
Imports System.Reflection
Imports System.Runtime.CompilerServices
Imports System.Runtime.InteropServices.RegistrationServices
Imports System.Xml
Imports System.Xml.XPathPublic Class Class1 ' Main Class, declared as *com interopable*, type of project : "type library", meaning it will need to be registered in windows, and type library will need to be exported
' you wlll need to make a batch file with the following commands in it, to check whether it has been introduced into the global assembly cache, browse your hard drive
' to windows/assembly and look for an entry named "Test", if it *is* listed there, then it will work.'regasm Test.dll 'regasm Test.dll /tlb:Test.dll 'regasm Test.dll /codebase /tlb:Test.dll 'gacutil /i Test.dll ' Put it into the folder where you already put test.dll, along with \*regasm.exe\* and \*gacutil.exe\* (obligatory) and then execute the bat file ' The type library is now registered and you can call its methods (the only working method is called "Method1") Public Shared RezultatiY ' vb.NET array to hold our data Public Function MethodNumber(ByRef numberz) ' Fetch the array of type integer or double (will be converted to double) RezultatiY = Nothing Dim Arrayzz() As Object Arrayzz = Nothing Arrayzz = numberz Dim NumberOfElements As Integer = UBound(numberz) - 1 ' We need to find the total number of elements ReDim RezultatiY(NumberOfElements) ' And then redimension our array to that number of elements For i As Integer = 0 To UBound(Arrayzz) - 1 Dim Temp As Double = CDbl(Arrayzz(i)) RezultatiY(i) = CDbl(Temp) My.Computer.FileSystem.WriteAllText("C:\\Temp\\TestingIntegersAndDoubles.txt", RezultatiY(i) & " " & i & " " & " " & RezultatiY(i).GetType.ToString & vbCrLf, True) Next End Function Public Function MethodString(ByRef Words) ' Fetch the array of type string RezultatiY = Nothing
Hey Hrizip, Thanks for the detailed reply. I googled a bit and found that the bracketing means forcing VBscript to pass the array by value rather by reference. And may I know which framework version you are using? We came across this post http://connect.microsoft.com/VisualStudio/feedback/details/331632/marshaler-bug-with-vbscript-arrays[^] and the guy commented that the problem (passing array from VBscript to .NET DLL thru COM) is only solved in .net framework 4.0. Thanks!
The UI should look beautiful, so do the coding
-
Hey Hrizip, Thanks for the detailed reply. I googled a bit and found that the bracketing means forcing VBscript to pass the array by value rather by reference. And may I know which framework version you are using? We came across this post http://connect.microsoft.com/VisualStudio/feedback/details/331632/marshaler-bug-with-vbscript-arrays[^] and the guy commented that the problem (passing array from VBscript to .NET DLL thru COM) is only solved in .net framework 4.0. Thanks!
The UI should look beautiful, so do the coding
-
Hey Hrizip, Thanks for the detailed reply. I googled a bit and found that the bracketing means forcing VBscript to pass the array by value rather by reference. And may I know which framework version you are using? We came across this post http://connect.microsoft.com/VisualStudio/feedback/details/331632/marshaler-bug-with-vbscript-arrays[^] and the guy commented that the problem (passing array from VBscript to .NET DLL thru COM) is only solved in .net framework 4.0. Thanks!
The UI should look beautiful, so do the coding
It is difficult to say at this point which framework we were using at that point, chances are we were using 3.5. We are still mostly using 3.5, only several machines have 4.0 installed. Thanks for the info on double bracketing, I remember going through hell and trying every possible thing to make this work, I havent commited to memory all those trials (and errors). Kinda not surprising that there is/was a bug in the framework itself, that would explain a great deal of things. The whole process of interoping with legacy apps is just horrible, making it work gulps down 80% of total time spent developing an app. Similar problems happen when you have to cross the managed/unmanaged barrier between apps, and between various C languages. I remember going thru hell trying to adapt c++ code to vb.net code across managed/unmanaged barrier. It also has problems marshalling various data types, and its also "trial and error" until you find the right combination.