Need help passing arrays from vb .NET to ActiveX control (*.ocx)



  • Hi all, 

    I have an application written in Visual Basic 6 that uses an ActiveX control written in Visual C++ 6. I'm moving the visual basic 6 application to visual basic .NET (2003). The problem is when I try to pass an array from the visual basic code as a parameter of a function of the control.
    In Visual Basic 6 the code is something like this:

    Dim dummy(10) as Long
    '...
    'some code
    '...
    call myActiveXControl.myFunction(dummy(0))


    myFunction expects a reference of the first element of an array of Integers. Passing the first element of the array works fine in visual basic 6.

    But if I try the above code in vb .NET, changing the definition of the array for this one (type Long in vb 6 is Integer in vb .NET) :

    Dim dummy(10) as Integer

    it does not work, the ActiveX control cannot even retrieve the contents of the array.

    I suppose the solution has something to do with marshaling, but I don't have any idea of what to do

    Any help would be appreciated

    Thanks in advance



  • I don't know a damn thing about .net or about ActiveX, but, if I understand what you're saying here, there's a type mismatch between a function whose argument is an array of integers and code that passes it a single integer. The function expects an array, which (implementation detail) is passed as a reference (pointer?) to the first member of the array.  Previously, VB translated array members passed as ByRef parameters to functions into a pointer to the array member; VB.net is instead creating a temporary value to evaluate dummy(0) into and then passing the method a pointer to that temporary.

    Try passing 'dummy' (no subscript) to myActiveXControl.myFunction, rather than dummy(0).

    Show the definition of myFunction?  It'd help a lot.
     



  • I am not sure here, but did you try to pass the array instead of the first element as the argument?

     

    like this:

    myActiveXControl.myFunction(dummy)



  • Thanks for your answers 

    The C++ function of the control expects a C-Style array, so it needs a reference to the first position of the array. In visual basic 6 one could pass the first position of the array and it worked fine.

    I cannot pass the array variable directly. Maybe it has something to do with marshaling or with tweaking the MSIL of the interop assembly a bit, but I'm new to .NET, so I don't have any idea of how to do this.

    Urlik 



  • @Urlik said:

    Hi all, 

    I have an application written in Visual Basic 6 that uses an ActiveX control written in Visual C++ 6. I'm moving the visual basic 6 application to visual basic .NET (2003). The problem is when I try to pass an array from the visual basic code as a parameter of a function of the control.
    In Visual Basic 6 the code is something like this:

    Dim dummy(10) as Long
    '...
    'some code
    '...
    call myActiveXControl.myFunction(dummy(0))


    myFunction expects a reference of the first element of an array of Integers. Passing the first element of the array works fine in visual basic 6.

    But if I try the above code in vb .NET, changing the definition of the array for this one (type Long in vb 6 is Integer in vb .NET) :

    Dim dummy(10) as Integer

    it does not work, the ActiveX control cannot even retrieve the contents of the array.

    I suppose the solution has something to do with marshaling, but I don't have any idea of what to do

    Any help would be appreciated

    Thanks in advance

    <FONT color=#0000ff>Ok i went and did a bunch of research. I'm too tired to put this specifically, but there's a way to use the system.runtime.interop.marshal. section to get a pointer to your managed memory so taht something unmanaged (your activex) can reference the data. i'm assuming you can't change the receiving end...</FONT>

    <FONT color=#0000ff>I've never actually bothered to use any activex or COM stuff, (and VB.NET loathes pointers and unmanaged memory)</FONT>



  • I've tried to use the system.runtime.interopservices.marshal but with no better results. I can use the Copy method to copy the data to an unmanaged memory pointer, but I don't know if is possible to pass this pointer to the function and how to do it.

    The function definition is

        Public Overridable Sub myFunction(ByRef ar As Integer) 

     

    The most annoying part is that with vb 6 it works fine, so I thought that it was a common migration issue... : (
     

     Any idea? I can't change the receiving end.



  • Did you try to call the method using myActiveXControl.myFunction(ByRef dummy)

     
    I *think* that the VB6 syntax you used will pass the array by reference while the VB.NET syntax you used will pass it by value (and thereby pass a copy of the array).

     
    Do you get any exceptions btw?
     

     



  • Have you found a solution to this issue? I'm having the same problem... I think it's a problem with the unmanaged memory zone where the active x runs, but I couldn't find a solution to this...

    Any help would be appriciated.



  • @Urlik said:

    Thanks for your answers 

    The C++ function of the control expects a C-Style array, so it needs a reference to the first position of the array. In visual basic 6 one could pass the first position of the array and it worked fine.

    I cannot pass the array variable directly. Maybe it has something to do with marshaling or with tweaking the MSIL of the interop assembly a bit, but I'm new to .NET, so I don't have any idea of how to do this.

    Urlik 

     

    What is the definition of the ActiveX control?

    If it wants a SafeArray, you should be ok in just passing in the array. But if it wants an int* then you have to declare your code as unsafe.



  • if you're still searching:

     try

    Dim yourArray(10) As long 'or whatever it is
    ' Create a GCHandle for the Array
    Dim gch As GCHandle = GCHandle.Alloc(yourArray)
     callToactivex.method(GCHandle.op_Explicit(gch))



  • @Cimpy said:

    if you're still searching:

     try

    Dim yourArray(10) As long 'or whatever it is
    ' Create a GCHandle for the Array
    Dim gch As GCHandle = GCHandle.Alloc(yourArray)
     callToactivex.method(GCHandle.op_Explicit(gch))

    He joined three years ago, posted those 3 posts and never came back, I'm sure he appreciates the help :)


Log in to reply