如何解决将数组参数从C#
我正在尝试将双精度数组传递给从C ++ DLL导入C#的函数。 该函数在C ++ DLL中看起来像这样(使用了调用约定cdecl):
__declspec(dllexport) void FunctionToImport(void* values,size_t numberOfValues,const char* someString);
在C#中导入:
[DllImport("DLLToImport.dll",CallingConvention = CallingConvention.Cdecl)]
public static extern void FunctionToImport(IntPtr values,int numberOfValues,string someString);
以这种方式从C#调用时:
double[] bytes = { 1.0,2.0,3.0,4.0 };
IntPtr testvalues = Marshal.AllocHGlobal(bytes.Length);
Marshal.Copy(bytes,testvalues,bytes.Length);
CSharpClass.FunctionToImport(testvalues,Marshal.SizeOf(testvalues),"someString";
Marshal.FreeHGlobal(testvalues);
我收到一个AccessViolationException,有时程序会崩溃。
将size_t模拟数组传递给库的正确方法是什么?
解决方法
我收到一个AccessViolationException,有时程序会崩溃。
由于bytes.Length为4,因此会出现异常,但实际上您需要分配4 * sizeof(double)个字节的内存。您将数组中的元素数量与需要分配的内存量混淆了。此外,Marshal.Sizeof(values)将为您提供IntPtr的大小,而我认为您需要元素计数。另外,C方法签名使这一点变得令人困惑:如果采用双精度数组,为什么参数void * []而不是double []或double *?您的C#数组命名为“字节”,但其中包含双精度数,这也使我怀疑C代码期望的类型。这个void类型不会与第二个参数“ numberOfValues”发生冲突,因为通常情况下,如果某些东西使用void *,它想知道字节数而不是值的数目。因此,我认为API也存在一些不清晰的地方。
[DllImport(“ DLLToImport.dll”,CallingConvention = CallingConvention.Cdecl)] public static extern void FunctionToImport(IntPtr values,int numberOfValues,字符串 someString); 如果您解决了上述问题,从而可以分配和复制正确的内存量,则可以使用此方法,但这是困难的方法。相反,让P / Invoke为您进行封送处理。尝试类似的东西:
[DllImport("DLLToImport.dll",CallingConvention = CallingConvention.Cdecl)]
public static extern void FunctionToImport(double[] values,int numberOfValues,string someString);
这简化了很多。现在,您几乎可以像C#函数一样调用此方法: 嘟嘟
double[] numbers = { 1.0,2.0,3.0,4.0 };
FunctionToImport(numbers,numbers.Length,"someString");
有时候您需要使用元帅,但我怀疑这不是其中之一。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。