Thanks for all that info Sergey.
Well, COM is needed because this is an (already released) device driver. The device is controlled, together with other devices, by a 3rd party software that uses COM for this purpose.
So it's something like this:
VARIANT_BOOL DoSomething(BYTE data1, BYTE data2, BYTE data3, BYTE data4);
VARIANT_BOOL DoSomethingToo(MyStruct* data);
DISP_FUNCTION_ID(foobar, "DoSomething", dispid_DoSomething, DoSomething, VT_BOOL, VTS_UI1 VTS_UI1 VTS_UI1 VTS_UI1)
DISP_FUNCTION_ID(foobar, "DoSomethingToo", dispid_DoSomethingToo, DoSomethingToo, VT_BOOL, VTS_UI4)
VARIANT_BOOL foobar::DoSomethingToo(MyStruct* data)
[id(3), helpstring("...")] VARIANT_BOOL DoSomethingToo(MyStruct* data);
unsigned char b;
It's all about DoSomethingToo() which is an attempt to replace DoSomething(). The problem with this code is, when called from C#, that there's an unhandled COMException TYPE_E_ELEMENTNOTFOUND. So i'm guessing there's something wrong (or missing) with the struct declaration.