c# - 将 pair<int,float> 的二维数组从 c# 传递到 c dll

标签 c# .net c dll pinvoke

我是 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/

相关文章:

c# - C#接口(interface)和继承的问题

c# - 我如何知道 Windows Mobile 是否支持此方法?

.net - DateTimeOffsetAdapter干扰DateTimeOffset对象的WCF序列化

.net - 为什么 .Net WPF DependencyProperties 必须是类的静态成员

c - 如何重复 scanf() n 次?

c - 线程无限期地等待计时器信号

c# - 执行 n++ 后的奇怪答案

c# - Xamarin.Forms:如何避免在 MVVM 绑定(bind)中对字符串进行硬编码

c# - 按定义的顺序调用多个方法

c - 这个 Valgrind 警告是什么意思? - 警告设置地址范围权限