Link to home
Start Free TrialLog in
Avatar of shruthiajrao
shruthiajrao

asked on

Interoperability issue between VC++ (ocx) & VB.NET applications

Hello,

 We are migrating a product from VB6 to VB.NET and facing an issue.
 This product interacts with a function defined in VC++ component (.ocx).

 1. VB6 & VB.NET function call:



result = TestFunc(Param1, Param2, Param3)

 2. VC++:
 a) Function definition in .CPP file:


long TestFunc(long FAR* Param1, const VARIANT FAR& Param2, long Param3)
       {
       ...
       }


 DISP_FUNCTION(Ctrl, "TestFunc", TestFunc, VT_I4, VTS_PI4 VTS_VARIANT VTS_I4)

 b) Function signature in .ODL file:


long TestFunc(long* Param1, VARIANT Param2, long Param3);

 c) Function signature in .h(header) file:


afx_msg long TestFunc(long FAR* Param1,  const VARIANT FAR& Param2, long Param3);


 "Param2" in above "TestFunc" is defined as byte array in VB6 & VB.NET.

 In VC++, the corresponding type for "Param2" in "TestFunc" is - "const VARIANT FAR& Param2".

 In VB6, the byte array values passed gets modified in VC++ "TestFunc" & the modified values are received in VB6 "Param2" variable.

 Issue in VB.NET:

 In VB.NET, the byte array values passed gets modified in VC++ "TestFunc".
 However, the modified values are not transferred from VC++ to VB.NET. The "Param2" variable still has the original values & not the modified values.

 Could you please provide us information on how to obtain the modified byte array values in VB.NET from the Variant variable in VC++ component?

 Thanks in advance.
ASKER CERTIFIED SOLUTION
Avatar of Jacques Bourgeois (James Burger)
Jacques Bourgeois (James Burger)
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of shruthiajrao
shruthiajrao

ASKER

Converting the .ocx to .net dll, is not option for us right know due to time constraint.
Any other suggestion?
As I told you, try passing an array of Object instead of an array of Byte, which usually works better when the COM object is defined for a variant.

Or, if you have the source code, modify the COM component so that it works with an array of Byte.

You can also try to pin the .NET array. This prevents the .NET object from moving inside of the heap when there is garbage collection, so that it has a fixed address.
Thank you for the suggestion. We will check by passing an array of objects.

We had also earlier changed the .ODL, .CPP, .H files signature of TestFunc in C++ to accept the value of Param2 as reference.

C++:

.ODL:

                long TestFunc(long* Param1, VARIANT* Param2, long Param3);
               
.CPP:

long TestFunc(long FAR* Param1, VARIANT* Param2, long Param3)
                                {
                                ...
                                }
                               
              DISP_FUNCTION(Ctrl, "TestFunc", TestFunc, VT_I4, VTS_PI4 VTS_PVARIANT VTS_I4)                        

.H files:

  afx_msg long TestFunc(long FAR* Param1, VARIANT* Param2, long Param3);
               
  #define VTS_PVARIANT        "\x4C"      // a 'VARIANT*'  
 
VB.NET:

Function declaration:
Public Overridable Function TestFunc(ByRef Param1 As Integer, ByRef Param2 As Object, Param3 As Integer) As Integer

Param2 declaration inside a user defined structure in vb.net:
Dim Param2() As Byte

Function call:
result = TestFunc(Param1, Param2, Param3)

The function declaration in VB.NET now shows ByRef for Param2.

However, when TestFunc() function is now called in VB.NET following error occurs:

"Type mismatch. (Exception from HRESULT: 0x80020005 (DISP_E_TYPEMISMATCH))"

Could you please provide us any information on this above type mismatch error?

Thanks.
When I was working in COM, I never used the Variant data type in my own code. It took too much space in memory and did not bring anything that I could do otherwise. So this is not something that I had to deal with.

What I know about the interaction of .NET with Variant is because I used .NET a lot to deal with Office, where Variant as quite common. We used to have big problems doing that in the first versions of .NET, when we had to rely on the automatically generated interop as a bridge. As I told you in my first answer, that does not work all the time. A lot of methods worked inconsistently if not at all. Microsoft solved that by providing a primary interop assembly (PIA) for Office applications, an interop that was debugged by its programmer to solve all the problems.

As I told you, a Variant in COM and an Object in .NET are not the same thing. Because of strong type checking, I suppose that the system detects that, thus the type mismatch.

There are ways to marshall the interaction between managed (.NET) and unmanaged (COM) arrays in C++. This is how interops deal with these problems. But although I am a VB programmer, I do not think it could be done in VB. VB rely completely on the interop to deal with COM. In C++, they do it by mixing managed and unmanaged code in the .NET application, but this is not possible in VB.
Avatar of Martin Liss
This question has been classified as abandoned and is closed as part of the Cleanup Program. See the recommendation for more details.