14

I am trying to pass a structure from C# into C++ library. I pass structure as an object, and C++ function expects it as a pointer (void *).

I am having problem passing the structure.

[DllImport("MockVadavLib.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr TheFunction([MarshalAs(UnmanagedType.LPStruct)] UserRec userRec);

Here is the run-time exception text I get:

"Cannot marshal 'parameter #1': Invalid managed/unmanaged type combination (this value type must be paired with Struct)."

Though I found an MSDN article that uses LPStruct in exactly this context.

This is my structure I'm trying to marshal:

[StructLayout(LayoutKind.Sequential)]
public struct UserRec {
    [MarshalAs(UnmanagedType.I4)]
    public int userParam1;
}

This is C++ function:

MOCKVADAVLIB_API tVDACQ_CallBackRec * TheFunction(void * userParams) {...

3 Answers 3

23

Try passing the structure as a ref parameter.

[DllImport("MockVadavLib.dll", CharSet = CharSet.Ansi)]
public static extern IntPtr TheFunction(ref UserRec userRec);

When you use a ref combined with a structure, it conceptually passes the address.

Sign up to request clarification or add additional context in comments.

3 Comments

You don't even need the [MarshalAs] in this case I think.
End working result: public static extern IntPtr TheFunction([MarshalAs(UnmanagedType.Struct), In] ref UserRec userRec); And [MurshalAs] here is just to make it explicit, but not required.
Isn't [In] ref better than ref because the marshaler won't bother copying back?
21

Incidentally, UnmanagedType.LPStruct is rarely, if ever, the correct MarshalAs argument. A quote from Adam Nathan who is a Microsoft employee:

UnmanagedType.LPStruct is only supported for one specific case: treating a System.Guid value type as an unmanaged GUID with an extra level of indirection.

2 Comments

Btw, thanks for the explanation of why this is so. That's what I really wanted.
(Wait, what is this madness? I used ref in the signature but not at the call site! The C# language must have an exception for COM interfaces?)
3

Some additional information followup regarding @Rytmis's post.

From https://learn.microsoft.com/en-us/dotnet/standard/native-interop/best-practices#guids:


DO NOT Use [MarshalAs(UnmanagedType.LPStruct)] for anything other than ref GUID parameters.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.