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

我的梦境 提交于 2021-02-19 07:25:11

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!