1

我是 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# 中定义此节点(或对)类型,然后将对节点的二维数组的引用传递给 c dll。

4

1 回答 1

0

它取决于 c 代码中 pair 的内存布局,但您可以在 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);

(可以使用 /unsafe 选项在 c# 中使用指针)

或者

    [DllImport("mydll.dll")]
    static extern void callMyDll(pair[] mypair);

(这个使用您通过“MarshalAs”属性指定的内存映射将托管内存复制到非托管内存=>更安全)

编辑:尽可能避免传递指针:在 C# 中实例化的对象的地址可以更改...或查看“固定”关键字参考

edit2:如果“pair”是一个 C++ 类(带有一个虚拟表)而不是一个结构,那么您必须void* vtableAddress;在其 C# 定义中为其成员添加 a。如果您想知道原因,请参阅有关虚拟表机制的更多文档(由 C++ 和几乎所有使用虚拟调用的编译语言使用)

于 2013-10-30T18:40:49.520 回答