我的程序需要控制一个硬件。供应商提供了一个为 C/C++ 语言设计的 DLL。 除了以下功能之外,大多数功能都通过了我的测试:
int32 ni845xSpiWriteRead(NiHandle DeviceHandle,
NiHandle ConfigurationHandle,
uInt32 WriteSize,
uInt8 * pWriteData,
uInt32 * pReadSize,
uInt8 * pReadData);
这个函数的文档在这里:
输入 NiHandle 设备句柄
从 ni845xOpen 返回的设备句柄。
NiHandle 配置句柄
从 ni845xSpiConfigurationOpen 返回的配置句柄。
uInt32 写入大小
要写入的字节数。这必须是非零的。
uInt8 * pWriteData
要写入的数据字节。
输出 uInt32 * pReadSize
指向读取字节数的指针。
uInt8 * pReadData
指向已读取字节的字节数组的指针 已存储。
我的 C# 代码在这里:
[DllImport("Ni845x", CallingConvention = CallingConvention.Cdecl)]
public static extern int ni845xSpiWriteRead(
long DeviceHandle, //In
long ConfigurationHandle, //In
int WriteSize, //In
IntPtr pWriteData, //In
IntPtr pReadSize, //Out
IntPtr pReadData //Out
);
我总是遇到 AccessViolationException
异常。我猜这是由指针输入/输出参数引起的。
调用Swrapper.ni845xSpiWriteRead()的代码在这里:
public void WriteData(int length, int[] writeArray)
{
byte[] writeDate = new byte[8];
int writeSize = writeDate.Length;
try
{
//Define pointers
IntPtr writeDataPointer = Marshal.AllocHGlobal(writeDate.Length);
IntPtr readDataSizePointer = Marshal.AllocHGlobal(writeDate.Length);
IntPtr readDataPointer = Marshal.AllocHGlobal(writeDate.Length);
//Copy value to write data pointer
Marshal.Copy(writeDate, 0, writeDataPointer, writeDate.Length);
int state = Ni845xNativeMethods.ni845xSpiWriteRead(_niHandle, _niConfigrationHandle, writeSize, writeDataPointer,readDataSizePointer,readDataPointer);
this.CheckStatus(state);
}
catch (Exception)
{
throw;
}
}
最佳答案
最有可能的 p/invoke 应该是:
[DllImport("Ni845x", CallingConvention = CallingConvention.Cdecl)]
public static extern int ni845xSpiWriteRead(
IntPtr DeviceHandle,
IntPtr ConfigurationHandle,
uint WriteSize,
[In] byte[] WriteData,
out uint ReadSize,
[Out] byte[] ReadData
);
您需要分配足够长度的 byte[]
以用作 ReadData
参数。想必您知道如何执行此操作。
我从表面上看,ReadSize
是一个输出参数。但是,如果它既是 in 又是 out,则将其声明为 ref
。
关于c# - 在 C# 中使用 C++ DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24795988/