Last Updated: 2009-08-11 2:30pm EDT
A few days ago I posted this question about some very strange problems. Well, I figured out what specifically was causing a build on one machine to not run on others and even came up with a work-around, but now it leaves me with a nice, specific question: Why?
To reproduce the problem, I create a new InteropUserControl and do the following:
- Add a new
public struct MyStruct
: - Give it a GUID and
ComVisible
attributes - Add a
GetMyStruct
member to the_InteropUserControl
interface and implement it inInteropUserControl
.
MyStruct
:
[Guid("49E803EC-BED9-4a08-B42B-E0499864A169")]
[ComVisible(true)]
public struct MyStruct {
public int mynumber;
}
_InteropUserControl.GetMyStruct()
:
[DispId(7)]
void getMyStruct( int num, ref MyStruct data );
(I have tried returning MyStruct
instead of passing by reference, as well.)
InteropUserControl.GetMyStruct()
implementation:
public void getMyStruct( int num, ref MyStruct data ) {
data = new MyStruct();
data.mynumber = num * 2;
}
I also sign the assembly and install it to the GAC and register with Regasm. Upon adding it to a new VB6 project and adding a call to GetMyStruct()
and compiling on our build machine, it refuses to run on other machines.
To get around this, I had to expose a class to COM instead of the struct, and basically change GetMyStruct
to this:
public void GetMyData( int num, MyClass data ) {
data.mynumber = num * 2;
}
In my actual project, I retrieve the struct internally, and then copy all the field values from the struct to the matching members on the instance of the class passed to the method by the client.
So why did a struct cause this behavior and a class worked fine? Is there some magic to exposing a struct to COM for using in VB6?
I think it may have something to do with OLE Automation.
Note: I also tried returning the struct rather than using a ref
parameter, but that did not change the behavior.
Edit to add link to project template:
Interop Forms Toolkit 2.0 is the original VB.NET project template and dll. I don't reference the dll, so you may not need to install this.
C# Translations of templates on CodeProject is what I used to create mine (the project template, not the item template). The VB.NET version generates the __InteropUserControl
event interface, the _InteropUserControl
interface, and a few relevant attributes automagically. Those are explicitly coded in the C# version, and that's about all that's different between the two.