Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I marshal a structure as a pointer to a structure?

Tags:

c#

pinvoke

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) {...
like image 213
THX-1138 Avatar asked May 06 '09 01:05

THX-1138


People also ask

Why do we need pointer to structure?

Pointer to structure holds the add of the entire structure. It is used to create complex data structures such as linked lists, trees, graphs and so on. The members of the structure can be accessed using a special operator called as an arrow operator ( -> ).

What is marshalling in C#?

Marshalling is the process of transforming types when they need to cross between managed and native code. Marshalling is needed because the types in the managed and unmanaged code are different.

Can we inherit structure in C#?

A structure type can't inherit from other class or structure type and it can't be the base of a class. However, a structure type can implement interfaces.

What is IntPtr C#?

The IntPtr type can be used by languages that support pointers and as a common means of referring to data between languages that do and do not support pointers. IntPtr objects can also be used to hold handles. For example, instances of IntPtr are used extensively in the System. IO.


2 Answers

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.

like image 176
Rytmis Avatar answered Sep 26 '22 02:09

Rytmis


Some additional information followup regarding @Rytmis's post.

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


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

like image 23
Joseph Lennox Avatar answered Sep 25 '22 02:09

Joseph Lennox