C# 非托管 PInvoke AccessViolation
c# unmanaged PInvoke AccessViolation
我有 C++ DLL。
当从 C# 中的此 DLL 调用方法时,AccessViolation 被抛出。
我的代码有什么问题?有人能帮我吗?
C++ 头文件部分:
typedef PVOID X_HANDLE;
XREADER_API BOOL ReaderOpen(X_HANDLE *pxHandle);
XREADER_API BOOL ReaderReceiveW26(X_HANDLE xHandle, LPVOID pBuffer, DWORD nBufferSize);
工作示例部分 C++:
X_HANDLE hReader;
unsigned char xKeyBuffer[3];
ReaderOpen(&hReader);
ReaderReceiveW26(hReader,xKeyBuffer,sizeof(xKeyBuffer));
我的 C# 代码:
[DllImport("reader.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
public static extern bool ReaderOpen(IntPtr reference);
[DllImport("reader.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
public static extern bool ReaderReceiveW26(IntPtr hReader, IntPtr pBuffer, uint xKeyBuffer);
static void Main(string[] args)
{
byte[] received = new byte[3];
IntPtr unmanagedPointer = Marshal.AllocHGlobal(received.Length);
Marshal.Copy(received, 0, unmanagedPointer, received.Length);
IntPtr hReader = Marshal.AllocHGlobal(sizeof(uint));
var qqq = uint.Parse((Marshal.SizeOf(typeof(byte)) * received.Length).ToString());
ReaderOpen(hReader);
while (true)
{
if (ReaderReceiveW26(hReader, unmanagedPointer, qqq))
{
Console.WriteLine("!");
}
}
}
在 ReaderReceiveW26(hReader、unmanagedPointer、qqq)处抛出 AccessViolation
感谢您的耐心等待!
感谢 Hast Passant 的评论!
如果我们想使用由非托管代码编辑的 IntPtr 或 smth,我们需要使用
out paramName
对于 PVOID,我们可以传递真正的 c# 类型。
工作示例:
[DllImport("reader.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
public static extern bool ReaderOpen(out IntPtr reference);
[DllImport("reader.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
public static extern bool ReaderReceiveW26(IntPtr hReader, byte[] pBuffer, uint xKeyBuffer);
我有 C++ DLL。 当从 C# 中的此 DLL 调用方法时,AccessViolation 被抛出。 我的代码有什么问题?有人能帮我吗? C++ 头文件部分:
typedef PVOID X_HANDLE;
XREADER_API BOOL ReaderOpen(X_HANDLE *pxHandle);
XREADER_API BOOL ReaderReceiveW26(X_HANDLE xHandle, LPVOID pBuffer, DWORD nBufferSize);
工作示例部分 C++:
X_HANDLE hReader;
unsigned char xKeyBuffer[3];
ReaderOpen(&hReader);
ReaderReceiveW26(hReader,xKeyBuffer,sizeof(xKeyBuffer));
我的 C# 代码:
[DllImport("reader.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
public static extern bool ReaderOpen(IntPtr reference);
[DllImport("reader.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
public static extern bool ReaderReceiveW26(IntPtr hReader, IntPtr pBuffer, uint xKeyBuffer);
static void Main(string[] args)
{
byte[] received = new byte[3];
IntPtr unmanagedPointer = Marshal.AllocHGlobal(received.Length);
Marshal.Copy(received, 0, unmanagedPointer, received.Length);
IntPtr hReader = Marshal.AllocHGlobal(sizeof(uint));
var qqq = uint.Parse((Marshal.SizeOf(typeof(byte)) * received.Length).ToString());
ReaderOpen(hReader);
while (true)
{
if (ReaderReceiveW26(hReader, unmanagedPointer, qqq))
{
Console.WriteLine("!");
}
}
}
在 ReaderReceiveW26(hReader、unmanagedPointer、qqq)处抛出 AccessViolation
感谢您的耐心等待!
感谢 Hast Passant 的评论! 如果我们想使用由非托管代码编辑的 IntPtr 或 smth,我们需要使用
out paramName
对于 PVOID,我们可以传递真正的 c# 类型。
工作示例:
[DllImport("reader.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
public static extern bool ReaderOpen(out IntPtr reference);
[DllImport("reader.dll", CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
public static extern bool ReaderReceiveW26(IntPtr hReader, byte[] pBuffer, uint xKeyBuffer);