Reputation: 33
I have the following C++ function (belongs to a COM interface, derived from IUnknown), which I want to call from C# code:
C++ declaration as documented:
HRESULT Function1([in] STRUCT1 *s1, [in, out] STRUCT2 *s2, [in] SIZE_T var1);
Declaration inside a working C++ program:
STDMETHOD(Function1)(
THIS_
__out STRUCT1 * s1,
__in_ecount_opt(var1) const STRUCT2 * s2,
SIZE_T var1
) PURE;
In C# territory I define the following:
[StructLayout(LayoutKind.Sequential)]
public struct STRUCT1
{
public uint member1; //HRESULT member1
public ulong member2; //SIZE_T member2
}
[StructLayout(LayoutKind.Sequential)]
public struct STRUCT2
{
public IntPtr member1; //VOID *member1;
public ulong member2; //SIZE_T member2;
public STRUCT3 member3; //STRUCT3 member3;
}
[StructLayout(LayoutKind.Sequential)]
public struct STRUCT3
{
public int member1; //int member1
}
I implement this function in C# as follows :
[ComImport, ComVisible(false), InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("…")]
public interface Iinterface1
{
……
uint Function1(ref STRUCT1 s1, ref STRUCT2 s2, ulong var1);
……
}
and I invoke the function like this:
STRUCT1 temp1 = new STRUCT1();
temp1.member1 = 0;
temp1.member2 = 0;
STRUCT2 temp2 = new STRUCT2();
STRUCT3 temp3 = new STRUCT3();
temp3.member1 = 0;
temp2.member1 = IntPtr.Zero;
temp2.member2 = 0;
temp2.member3 = temp3;
ulong var1 = 1;
res1 = COMobject.Function1(ref temp1, ref temp2, var1);
When function is executed I get an Access Violation Exception :
“An unhandled exception of type 'System.AccessViolationException' occurred in prog1.exe Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt. “
I implemented most of functions of the same interface with no problems, as well as a lot of other interfaces in this application. This one really puzzles me.
I would really appreciate your help on this..
Thank you in advance.
Upvotes: 3
Views: 1762
Reputation: 2548
COM-Interop has a rather strange set of rules, you have to really be "into it" to reason about it. Many things can go wrong "silently" and you just have to figure it out the hard way. In similar situations, here's what I'd do to try to figure things out:
Try to use the COM interface from PowerShell. It gives a nice "second POV" to see if the problem may be in your C# code. Also, it's usually much easier to do testing this way, pushing various data in.
Do some debugging. Use the MessageBox() trick to halt the execution of C++ code at the start of the C++ (member) function, then attach the debugger and see what's going on.
The previous point can be time consuming, sometimes a bunch of printfs of the parameters and other state can help you figure out what's going on. Combined with PowerShell, you can have a lot of inputs and see which cause issues and what kind of issues.
Upvotes: 1