I'm interfacing from .NET to an ActiveX DLL and I'm having
one problem I cant figure out.
(The ActiveX DLL is from a vendor so I cant change it.)
There's a function in the ActiveX DLL which returns a type
of Object, but it's actually an instantiation
of another class defined in the ActiveX DLL, and I can't figure out
how to reference it....
Let me give a simple example of the problem: There are two classes defined
in the ActiveX DLL:
ClassA
ClassB
I create an instance of ClassA. ClassB can only be instantiated within the
ActiveX Dll and
there's a function within ClassA to do this and return a reference to it.
However the
parameter type is object so the Interop doesn't "know" to convert it to a
managed class.
EX:
So if I were writing VB6 code I'd have this:
'''VB6 Code
Dim myClassA as new ClassA 'create an instance of A
Dim myClassB as ClassB 'create a variable but not an instance
'the GetClassB function does not return a type of ClassB but of Object.
Call ClassA.GetClassB(myClassB) 'call A to get the instance of B
'now I can use ClassB
Call ClassB.DoStuff(myVar, etc) ' this works fine
'''end VB6 code
So when I try to do this .NET, it blows up. The cast from object to ClassB
doesn't throw an error but when I try to use myClassB it throws
a NullReference exception.
// c# code....
MyActiveXLib.ClassA myClassA = new MyActiveXLib.ClassA();
MyActiveXLib.ClassB myClassB;
Object myClassB_object
//Again, the parameter is of type Object.
myClassA.GetClassB(out myClassB_object);
//this cast does NOT throw an error....
myClassB = myClassB_object as MyActiveXLib.ClassB;
//This will throw an System.NullReferenceException....
myClassB.doStuff(....);
// END c# code.....
I'm sure this has everything to do with the fact that I'm trying
to reference an unmanaged object from managed code.
I've done a little Interop.Marshal work but I don't
know how to marshal an instantiation of a class.
Questions:
-Is there a way to copy or reference a class from unmanaged to managed code?
-If I can copy it, do I need to know how big the instance of ClassB is
before I copy it?
-Is there a way to modify the interop DLL that was built for me by .NET to
have it convert the
parameter from Object to ClassB??
Seems like there should be a straight forward way to marshal an ActiveX
class but I don't see anything
in the Interop.Marshal class.
Any help is GREATLY appreciated!!!
Thanks!
Steve
Steve - 01 Nov 2005 16:12 GMT
(Read original post below then go to bottom for my solution.)
PLEASE reply to this if you can accomplish the same thing
without using the seperate "convert" function.
> I'm interfacing from .NET to an ActiveX DLL and I'm having
> one problem I cant figure out.
[quoted text clipped - 75 lines]
> Thanks!
> Steve
I was able to solve this problem like this:
//BEGIN C# code.....
//.....
MyActiveXLib.ClassA myClassA = new MyActiveXLib.ClassA();
MyActiveXLib.ClassB myClassB;
Object myClassB_object = null;
//Again, the parameter is of type Object.
myClassA.GetClassB(out myClassB_object);
//this calls the function below
myClassB = ConvertToClassB(myClassB_object);
//This will NOT throw an System.NullReferenceException....
myClassB.doStuff(....);
//.......
//This is a seperate function which converts (marshals) the type....
private MyActiveXLib.ClassB ConvertToClassB(
[MarshalAs(UnmanagedType.CustomMarshaler,
MarshalTypeRef=typeof(MyActiveXLib.ClassB))] object oClassB)
{
MyActiveXLib.ClassB TempClassB = oClassB as MyActiveXLib.ClassB;
return TempClassB;
}
//END C# code