VB6 Option Type for .NET Type

I have a VB6 code that cannot be easily changed, which looks like this:

Dim cCount as Long Dim rCount as Long Dim result() Set mx = CreateObject("Component.Class") Dim rtn = mx.GetList(rCount,cCount,result) 

The method that it calls is currently a component of VB6, which we ported to .NET with one problem. We do not know what type the result () is looking for, since it is the type of the variant. We tried an object, an object [], an object [] [], a string, a string [], etc., None of which worked.

Here is an example:

 public bool GetList(ref long rCount, ref long cCount, ref object result) { ... } 

I even tried setting the third parameter to VariantWrapper, as it will add ByRef as needed:

 public bool GetList(ref long rCount, ref long cCount, VariantWrapper result) { ... } 

Any ideas what I can set for the incoming result so that I don't have an unhandled exception?

I created a test interface (for COM), a test class, and a VB6 test application to make sure this is a problem with the option. So, it is defined as follows:

.NET Interface:

 [DispId(1)] [ComVisible(true)] string Test(ref object[] value); 

Method VB 6:

 Private Sub Command1_Click() Set mx = CreateObject("Component.Class") Dim result() MsgBox mx.Test(result) End Sub 

Same problem as described above. In VB6, it just kicks me out. If I compile and run it, I get a generic .NET exception, and it throws me out.

+4
source share
4 answers

Your C # declaration is incorrect. VB6 "Long" 32-bit for historical reasons. This is an int on the C # side. If the stack frame is erroneous, you have no chance of passing the result argument correctly.

It should be SafeArray options, object [] in C #.

+4
source

Place a breakpoint on the line mx.GetList(rCount,cCount,result) . After you click, add the expression "quick look" mx.GetList(rCount,cCount,result) . The toolwindow window should show you what the resulting runtime type is. Most likely, it is "comresult" and will not provide much information, but it can give a hint to the return type.

+1
source

I think the ref keyword may cause some problems here. Types must match exactly in order to work.

However, if your method simply accepts a reference to any value of object by value (instead of ref ), it can get something passed as everything comes from object in .NET.

How well this translates to VB6 / COM interoperability, I don't know. But it seems that it is at least worth it:

C # code :

 public string GetTypeName(object value) { return value.GetType().FullName; } 

VB6 Code :

 Set mx = CreateObject("Component.Class") Dim result() MsgBox mx.GetTypeName(result) 

Does this give you anything?


Here is an idea. I could be wrong here - I don't have much experience porting VB6 applications to .NET - but it seems to me that if you can get at least (the C # equivalent) of this line ...

 Set mx = CreateObject("Component.Class") 

... then you are golden. You can use reflection to find out what parameters the GetList method wants to use.

First get a System.Type object representing the mx type:

 Type mxType = mx.GetType(); 

Then find the GetList method for this type:

 MethodInfo[] getListMethods = mxType.GetMember("GetList") .OfType<MethodInfo>() .Where(m => m.GetParameters().Length == 3) .ToArray(); 

This will give you an array of MethodInfo[] all public GetList overloads with three parameters. From here, the possible result types will be:

 Type[] possibleResultTypes = getListMethods .Select(m => m.GetParameters()[2].ParameterType) .ToArray(); 
+1
source

I only know how it is used in .Net, where you pass the link to Variant as follows:

  int port = 2; object pvPort = new System.Runtime.InteropServices.VariantWrapper(port); gimp.SetPort(ref pvPort); 

After that, place a breakpoint and check the type of option if you are not sure about it.

The main VariantWrapper is to use VariantWrapper so that the DLL understands.

0
source

Source: https://habr.com/ru/post/1315574/


All Articles