使用BYTE *输出导入DLL时出现问题

时间:2012-06-14 12:46:09

标签: c# pinvoke marshalling dllimport

我正在将一个函数从非托管DLL导入C#。 C ++函数签名如下

int RF_PowerOnEx(int nDev, int nCardType, DWORD* pdwRXSize, BYTE* lpbRXData)

我按如下方式导入

[DllImport("TP9000.dll")]
public static extern int RF_PowerOnEx(int nDev, int nCardType, out int pdwRXSize, out byte[] lpbRXData);

但这样做会给我一个System.AccessViolationException。我已成功导入除此特定功能之外的其他功能。 pdwRXSize和lpbRXData都被视为输出。初始化整数和缓冲区,然后传递给函数,然后填充缓冲区。救命!!!!我似乎能够将输入参数传递到DLL但无法获取输出参数。我试过传递一个Stringbuilder对象无济于事。有谁能够帮我?谢谢!

编辑:错字

3 个答案:

答案 0 :(得分:2)

我建议您像这样声明托管签名

public static extern int RF_PowerOnEx(int nDev, int nCardType, out int pdwRXSize, [out] IntPtr lpbRXData);

然后使用应在pdwRXSize中设置的长度信息直接从非托管内存中“手动”对字节数组进行编组。

你真的需要了解更多关于函数实现的信息:特别是调用者应该做些什么来释放包含数据缓冲区的内存?

答案 1 :(得分:1)

它不是out byte[],相当于BYTE **。使它只是普通字节[]。 pdwRXSize为ref,将其设置为数组的大小。这样称呼:

byte[] buffer = new byte[666];
int size = buffer.Length;
int retval = RF_PowerOnEx(device, cardtype, ref size, buffer);
if (retval == okay) processData(buffer, size);

你必须对所需的数组大小进行有根据的猜测。

答案 2 :(得分:0)

抛出

EntryPointNotFoundException因为.NET声明的名称不适合非托管声明(因为下划线)。

尝试:

    [DllImport("TP9000.dll", EntryPoint = "RF_PowerOnEx")]
    public static extern int RFPowerOnEx(int nDev, int nCardType, out int pdwRXSize, out byte[] lpbRXData);