Que*_*ueg 8 .net c# dll pinvoke interop
假设我有一个结构:
typedef struct {
float x;
float y;
float z;
int ID;
} Vertex;
Run Code Online (Sandbox Code Playgroud)
和一个C++函数:
float first(Vertex* ptr, int length){ //really silly function, just an example
Vertex u,v;
u.x = ptr[0].x; //...and so on, copy x,y,z,ID
v.x = ptr[1].x;
return (u.x * v.x + u.y * v.y + u.z * v.z);
}
Vertex* another(float a, int desired_size){
Vertex v = (Vertex*)malloc(desired_size*sizeof(Vertex));
v[0].x = a;
v[1].x = -a; //..and so on.. make some Vertices.
return v;
}
Run Code Online (Sandbox Code Playgroud)
首先 - 我的IDE.我正在使用Visual Studio 2010,构建一个C#(4.0)应用程序; C++部分也是在VS2010中构建的.
我知道如何构建一个C/C++代码的DLL并在C#应用程序中使用它,但直到今天我只使用原始参数并返回如下值:
[DllImport("library.dll", CharSet = CharSet.Ansi, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
public static extern int simple(int a, int b);
Run Code Online (Sandbox Code Playgroud)
今天我需要通过一个阵列的结构(如在上面的例子)..也许还接收一回..
如何将C#类"翻译"为C结构(反之亦然)?
结构可以像这样声明:
[StructLayout(LayoutKind.Sequential)]
public struct Vertex {
public float x;
public float y;
public float z;
public int ID;
}
Run Code Online (Sandbox Code Playgroud)
接下来,您需要确定一个调用约定.几乎可以肯定你的C++代码编译cdecl.让我们坚持下去.
该函数首先很容易从C#调用:
[DllImport("library.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern float first(Vertex[] vertices);
Run Code Online (Sandbox Code Playgroud)
请注意,您不应该SetLastError在这里使用- 那是Windows API函数.而且没有必要设置,CharSet因为这里没有文字.
现在,another事情变得更加复杂.如果您可以在C#代码中分配内存,那么这绝对是可行的方法.
void PopulateVertices(Vertex *vertices, int count)
{
for (int i=0; i<count; i++)
{
vertices[i].x = ....
}
}
Run Code Online (Sandbox Code Playgroud)
在C#端你声明它是这样的:
[DllImport("library.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void PopulateVertices(Vertex[] vertices, int count);
Run Code Online (Sandbox Code Playgroud)
并称之为这样
Vertex[] vertices = new Vertex[2];
PopulateVertices(vertices, vertices.Length);
Run Code Online (Sandbox Code Playgroud)
如果你不想在围栏的C#侧分配,那么就这样做:
CoTaskMemAlloc.IntPtr.Marshal.PtrToStructure和一些指针算法将返回数组封送到C#数组中.Marshal.FreeCoTaskMem释放本机模块中分配的内存.但是,如果您需要我的建议,请尝试坚持在托管代码中分配数组.
| 归档时间: |
|
| 查看次数: |
4483 次 |
| 最近记录: |