简体   繁体   中英

Calling a c-method with a c-style array as a parameter from C# .NET

I have a method defined in an unmanaged DLL:

int foo(somestruct * vector, int size)

How can I call this method from C#? Essentially, I want to complete the following snippet in my code:

[StructLayout(LayoutKind.Sequential), Serializable]
public struct somestruct
{
    //Whatever.
};

[DLLImport("some.dll")]
public static extern int foo( ???? );

Thanks.

It's much simpler than you think.

[DLLImport("some.dll")]
public static extern int foo(somestruct[] vector, int size);

The one thing to consider is marshaling direction. The runtime makes some decisions on whether to marshal the array before the call, after the call, or both. To make sure it makes the right decision, you may want to use In and/or Out attributes.

[DLLImport("some.dll")]
public static extern int foo([In] somestruct[] vector, int size);
// will only marshal the array to native memory before the call

[DLLImport("some.dll")]
public static extern int foo([Out] somestruct[] vector, int size);
// will only marshal the array to managed memory after the call

[DLLImport("some.dll")]
public static extern int foo([In, Out] somestruct[] vector, int size);
// will marshal the array both ways

On the other hand, if somestruct is blittable , then no marshaling is necessary, as the runtime can just pin the array and pass a pointer to the managed copy.

LPArray should be correct.

Is the definition of somestruct correct? Is your C int 32 bits, or do you maybe have a mismatch there?

Maybe post the definition you tried also in the question, this may clarify things.

Yes, as far as I know you have to marshal that array manually using IntPtr . There was a question like this not long ago, check it out here . The other approach is to rewrite you native code into managed-C++ or create a C++-wrapper which calls the DLL for you.

.NET interop has no problem with struct as well as unmanaged array. You can define struct in C# and tell it to layout sequentially through custom attribute so it can map to you C struct. For array, you can use LPArray or even IntPtr and marshalling it yourself. You will need to use DllImport attribute to annotate the Dll method that you want to call in unmanaged code.

One other thing that is not obvious from your source code is the actualy C method. Have you declared it correctly as API export interface using __declspec (dllexport) ? and if you are compiling/coding it in C++ environment, then you should also include extern "C" in the beginning to make sure that the api interface is expose in the DLL correctly using C linking (naming convention) to prevent name decoration by C++ compiler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM