我是c#编程的新手。我有一个c函数,我想从.NET接口调用。所以我为这个函数创建了一个dll。到目前为止,一切都很好。这个函数接受一个输入参数,它是一对数组的数组:
typedef pair<int,float> Node;
typedef Node** DATA;
c函数的函数原型是:
void Train(DATA X, float* Y, float* W);
为了在.NET接口中使用此功能,首先我必须将两个数组中的数据转换为Node类型。类似的东西:
DATA D = new Node*[2];
D[0] = new Node[5];
D[1] = new Node[2];
for(int i = 0 ; i < 5 ; i++){
D[0][i].first = i;
D[0][i].second = i+5;
}
for(int i = 0 ; i < 2 ; i++){
D[1][i].first = i;
D[1][i].second = i+5;
}
现在,我需要帮助在c#中定义此Node(或对)类型,然后将对Node的2-D数组的引用传递给c dll。
答案 0 :(得分:0)
它依赖于c代码中对的内存布局,但您可以在C#中定义:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 4)]
public struct pair
{
[MarshalAs(UnmanagedType.I4)]
public int first;
[MarshalAs(UnmanagedType.R8)]
public double second;
}
并使用它:
[DllImport("mydll.dll")]
static extern void callMyDll(pair** mypair);
(指针可以使用c#using / unsafe选项)
或
[DllImport("mydll.dll")]
static extern void callMyDll(pair[] mypair);
(这个使用您通过“MarshalAs”属性指定的内存映射将托管内存复制到非托管内存=>更安全)
编辑:尽量避免传递指针:C#中实例化的对象地址可能会发生变化......或者查看"fixed" keyword reference
edit2:如果“pair”是C ++类(带有虚拟表)而不是结构,则必须在其C#定义中为其成员添加void* vtableAddress;
。
如果您想知道原因(使用C ++和几乎所有使用虚拟调用的编译语言),请参阅有关虚拟表机制的更多文档。