I have a COM interface with an IDL file with the following declared:
typedef [uuid(D7B6C495-FFF3-11E0-8A39-08002700D831)]
struct PORT_CONFIG
{
unsigned char rack;
unsigned short port;
unsigned char offset;
} PORT_CONFIG;
[object, uuid(D7B6C492-FFF3-11E0-8A39-08002700D831), dual, nonextensible, pointer_default(unique)]
interface IMED704 : IDispatch
{
[id(5), helpstring("method PortConfig")] HRESULT PortConfig([in] SAFEARRAY(PORT_CONFIG) portCfg, [in, defaultvalue(-1)] VARIANT_BOOL clearInputs);
};
Now in my C# program I am trying to call the PortConfig method:
PORT_CONFIG[] portCfg = new PORT_CONFIG[12];
// ...Initialize code goes here
dig704.PortConfig(portCfg, true);
However the program throws an exception when the method is called. What am I doing wrong?
The exception is:
The parameter is incorrect. (Exception from HRESULT: 0x80070057 (E_INVALIDARG))
More information if I try the following:
IntPtr pointer = Marshal.GetITypeInfoForType(typeof(PORT_CONFIG));
The exception that I receive is:
The specified type must be visible from COM.\r\nParameter name: t
I now have the answer to my own problem. For some reason the interop layer fails on SAFEARRAY parameters when the interop type is embedded (the default in VS2010). To work around this issue right-click the reference to the COM object and set Embed Interop Type to False.
I wish that I could take credit for figuring out this answer, but the credit belongs to Michael Taylor:
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/1325d24c-db0f-43a1-9780-b68a843d816b