我是 C# 编程新手。我在 c 中有一个函数,我想从 .NET 接口(interface)调用它。所以我为这个功能创建了一个dll。到目前为止一切正常。这个函数接受一个输入参数,它是一对数组的数组:
typedef pair<int,float> Node;
typedef Node** DATA;
c函数的函数原型(prototype)是:
void Train(DATA X, float* Y, float* W);
为了在 .NET 界面中使用此函数,首先我必须将两个数组中的数据转换为节点类型。像这样的东西:
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# 中定义此节点(或对)类型,然后将对节点的二维数组的引用传递给 c dll。
最佳答案
这取决于pair在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# 中使用/unsafe 选项)
或
[DllImport("mydll.dll")]
static extern void callMyDll(pair[] mypair);
(这个使用您通过“MarshalAs”属性指定的内存映射将托管内存复制到非托管内存=>更安全)
编辑:尽可能避免传递指针:在 C# 中实例化的对象的地址可以更改...或参见 "fixed" keyword reference
edit2:如果“pair”是一个 C++ 类(有一个虚拟表)而不是一个结构,那么你必须在它的成员前面加上一个 void* vtableAddress;
在其 C# 定义中。
如果您想知道原因(由 C++ 和几乎所有使用虚拟调用的编译语言使用),请参阅有关虚拟表机制的更多文档
关于c# - 将 pair<int,float> 的二维数组从 c# 传递到 c dll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19689307/