我正在编写调用 C 库的 C# 代码以及一些我不太清楚的内容。
C 函数具有此签名:
double* DoSomeStuff(double* input,int numberOfElements);
我将函数映射为:
[System.Runtime.InteropServices.DllImportAttribute("myDll.dll", EntryPoint="DoSomeStuff")]
public static extern System.IntPtr DoSomeStuff(ref double input, int numberOfElements) ;
输入值是一个数组,因此 C 函数需要一个连续的内存布局。我对 C++ 比 C# 更熟悉。在 C++ 中,我使用 std::vector 来存储数据,然后我将使用 data() 方法获取指针并与 C 代码交换信息。 std::vector 保证连续的布局内存。
我可以在 C# 中使用哪种数据结构? C# 中有类似 std::vector 的东西吗?
我之前遇到过同样的字符串问题(在 C++ 中,std::string 只是一个 std::vector 加上一些修饰)。我已经使用以下方法解决了问题:
System.IntPtr stringExample = Marshal.StringToHGlobalAnsi("StringExample");
静态函数为我完成了这项工作。其他类型有类似这个功能吗?
我已经问了太多问题,我认为最重要的一个是:解决这类问题的最佳实践是什么?
谢谢
最佳答案
1)
将输入定义为 IntPtr:
[System.Runtime.InteropServices.DllImportAttribute("myDll.dll", EntryPoint="DoSomeStuff")]
public static extern System.IntPtr DoSomeStuff(IntPtr input, int numberOfElements) ;
2)
在 fixed 中创建一个数组 block ,然后从指针创建一个 IntPtr,然后将其传递给 DoSomeStuff
。
double[] input = new double[20];
IntPtr result = IntPtr.Zero;
fixed(double* d = &input[0])
{
result = DoSomeStuff(new InptPtr(d), 20);
}
...
fixed
block 的原因 是为了让 GC 在非托管代码填充数组时不会移动数组。
关于c# - 如何将 C 数组映射和编码为 C# 代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5219995/