PInvoke - 方法的类型签名与 PInvoke 不兼容
Posted
技术标签:
【中文标题】PInvoke - 方法的类型签名与 PInvoke 不兼容【英文标题】:PInvoke - Method's type signature is not PInvoke compatible 【发布时间】:2013-02-23 08:43:52 【问题描述】:这是我尝试在 C# 中使用的头文件签名和 C 代码:
__declspec(dllexport) emxArray_real_T *emxCreateWrapper_real_T(real_T *data, int32_T rows, int32_T cols);
struct emxArray_real_T
real_T *data;
int32_T *size;
int32_T allocatedSize;
int32_T numDimensions;
boolean_T canFreeData;
;
emxArray_real_T *emxCreateWrapper_real_T(real_T *data, int32_T rows, int32_T
cols)
emxArray_real_T *emx;
int32_T size[2];
int32_T numEl;
int32_T i;
size[0] = rows;
size[1] = cols;
emxInit_real_T(&emx, 2);
numEl = 1;
for (i = 0; i < 2; i++)
numEl *= size[i];
emx->size[i] = size[i];
emx->data = data;
emx->numDimensions = 2;
emx->allocatedSize = numEl;
emx->canFreeData = FALSE;
return emx;
我目前正在尝试在 C# 中按如下方式调用它:
[DllImport(@"C:\bla\bla.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern emxArray_real_T emxCreateWrapper_real_T(double[,] data, int rows, int cols);
double[,] array2D = new double[,] 1 , 3 , 5 , 7 ;
var x = emxCreateWrapper_real_T(array2D, 1, 4);
但得到:
Method's type signature is not PInvoke compatible.
emxArray_real_T
目前看起来像这样:
[StructLayout(LayoutKind.Sequential)]
public struct emxArray_real_T
//public IntPtr data;
//public IntPtr size;
double[] data;
int[] size;
public int allocatedSize;
public int numDimensions;
[MarshalAs(UnmanagedType.U1)]
public bool canFreeData;
【问题讨论】:
emxArray_real_T
是什么?问题可能出在那个方向。
【参考方案1】:
存在多个问题。首先,您的 C++ 函数返回一个指针 (emxArray_real_T *),但您的导入声明返回一个结构。那是行不通的。此外,您在导入声明中将数据声明为 double[,],但在结构中声明为 double[]。建议:
用类替换结构 确定数据是 double[] 还是 double[,] 还要检查 real_T 的最终大小。我相信它是一个平台相关变量,可以是浮点数(32 位)或双精度(64 位)。【讨论】:
我已经按照您的建议做了,但得到:尝试读取或写入受保护的内存。这通常表明其他内存已损坏。顺便说一句,typedef double real_T - 我过去使用 C# double 没有问题的 real_T ... 是的,所以您已经完成了第一步。现在你还有其他问题。我相信您在 SO 上还有另一个关于正确编组此 emxArray_real_T 的问题。你按照建议做了吗?如果您需要更多帮助,请粘贴完整的 C++ 结构定义。 将写另一个问题。谢谢!以上是关于PInvoke - 方法的类型签名与 PInvoke 不兼容的主要内容,如果未能解决你的问题,请参考以下文章
托管调试助手 "PInvokeStackImbalance":的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调
如何检查检查PInvoke签名的调用约定和参数与非托管的目标签名是不是匹配?
C# DllImport“调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配 ”