【问题标题】:C# Marshaling an ushort/ulong arrayC# 编组一个 ushort/ulong 数组
【发布时间】:2015-03-09 22:08:29
【问题描述】:

我有一个 C-DLL + 头文件并尝试从 C# 调用/调用函数。我还有一些关于如何使用该函数的示例 C++ 代码。这是函数定义:

int GetData(unsigned char* buffer, long bufferSize);

更有趣的部分是示例代码以及如何调用函数:

if(dataSize == 16)
{
  unsigned short* usData = new unsigned short[m_numX * m_numY * 3 / 2];
  GetData( (unsigned char*)usData, m_numX * m_numY * sizeof(unsigned short)  );
} 
else if (dataSize == 32) 
{
  unsigned long* ulData = new unsigned long[m_numX * m_numY];
  GetData( (unsigned char*)ulData, m_numX * m_numY * sizeof(unsigned long)  );
}

因此,根据 dataSize 变量,实际数据数组可以是 ushort 或 ulong。但是,它始终作为无符号字符指针传递。 为了简单起见,我只是尝试让至少一种变体起作用。这是我为dataSize = 16尝试的代码

[DllImport("External.dll", EntryPoint = "GetData", CharSet = CharSet.Unicode, CallingConvention =      CallingConvention.Cdecl)]
public static extern int GetData(ref ushort[] pBuffer, long lBufferSize);

long bufferSize1 = numX * numY * 3 / 2;
long bufferSize2 = numX * numY * sizeof(ushort);
ushort[] data = new ushort[bufferSize1];

GetData(ref data, bufferSize2)

如果我运行上面的代码,应用程序将退出并出现“访问冲突”异常。这通常意味着,不安全的代码试图写入缓冲区限制或 p/invoke 声明有错误。我尝试了巨大的缓冲区(它可以保存我期望的任何类型的数据),但我的猜测是,我的错误在声明中。

我还尝试在 p/invoke 声明中将缓冲区声明为 byte[](因为示例将其转换为 unsigned char*)和 ulong。我作为参考传递的实际缓冲区相同。错误依旧。

我怎样才能做到这一点?

【问题讨论】:

  • 没有完整的代码示例,不可能提供具体的建议。但我要指出,C++ long 等价于 C# int。因此,您的 p/invoke 方法声明与非托管代码不匹配(即,为缓冲区大小传递 64 位 int 而非托管代码需要 32 位 int)。仅此一项就可以解释这次崩溃。

标签: c# c++ c pinvoke dllimport


【解决方案1】:

几个错误:

  1. 数组不能作为ref 传递。那是因为ref ushort[] 匹配unsigned short**
  2. C++ long 与 Windows 上的 C# long 不匹配。前者是 32 位,后者是 64 位。

你需要像这样导入:

[DllImport("External.dll", CallingConvention =      CallingConvention.Cdecl)]
public static extern int GetData(
    [Out] ushort[] pBuffer, 
    int lBufferSize
);

为方便起见,对 32 位数据变体使用重载是完全合理的:

[DllImport("External.dll", CallingConvention =      CallingConvention.Cdecl)]
public static extern int GetData(
    [Out] uint[] pBuffer, 
    int lBufferSize
);

同样,byte 数组的重载在您需要时也是有效的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多