问题
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.
回答1:
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.
回答2:
Have a look at DllImport
attribute:
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.dllimportattribute.aspx
This is exactly what you need.
This tutorial: http://msdn.microsoft.com/en-us/library/hk9wyw21.aspx might be specifically on your problem.
One more link on the problem: http://msdn.microsoft.com/en-us/library/z6cfh6e6.aspx#cpcondefaultmarshalingforarraysanchor2
回答3:
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.
回答4:
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.
回答5:
.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.
来源:https://stackoverflow.com/questions/2341595/calling-a-c-method-with-a-c-style-array-as-a-parameter-from-c-sharp-net