C++ 函数到 C#
C++ function to C#
我对 C++ 编程完全陌生。我需要从 C# 调用 C++ 函数。
C++ 函数是:
BOOL Usb_Init(HWND hwnd);
我试过:
[DllImport("UsbComm.dll", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool Usb_Init( out IntPtr hwnd);
我收到错误消息:
PInvoke signature does not match the unmanaged target signature.
如何调用上面的C++方法?
BOOL
在 <windef.h>
中定义为 int
您需要在 C# 的导出声明中使用 int
。提示:值为0等于false
;其他都是 true
.
public static extern int Usb_Init(out IntPtr hwnd);
而且,您的调用约定也可能是错误的。尝试 CallingConvention
的每个枚举
编辑:工作签名是
[DllImport("UsbComm.dll", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int Usb_Init(out IntPtr hwnd);
C++ 代码: 确保 Usb_Init 的定义应如下所示:
extern "C" __declspec(dllexport) BOOL __stdcall Usb_Init(HWND hwnd)
{
return TRUE;
}
C#代码:
using System;
using System.Runtime.InteropServices;
namespace Win32DllClient
{
class Program
{
[DllImport("UsbComm.dll", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
public static extern bool Usb_Init(out IntPtr hwnd);
static void Main(string[] args)
{
IntPtr hwnd = new IntPtr(0);
var ret = Usb_Init(out hwnd);
}
}
}
我看到问题中的代码有以下错误:
- C++代码使用
cdecl
,C#代码使用stdcall
。那不匹配。
- C++ 代码按值传递
HWND
。 C# 代码有一个 IntPtr
作为 out
参数传递。那不匹配。
DllImport
属性有多个虚假参数。
正确的 C# 声明是:
[DllImport("UsbComm.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool Usb_Init(IntPtr hwnd);
您可以将 ExactSpelling
设置为 true
,但我认为没有令人信服的理由这样做。如果您愿意,请随时添加。指定 CharSet
没有意义,因为不涉及文本。 SetLastError = true
可能是一个错误。根据我的判断,非托管函数调用 SetLastError
的可能性不大。我的期望是您在尝试消除错误时添加了 SetLastError = true
。
我对 C++ 编程完全陌生。我需要从 C# 调用 C++ 函数。
C++ 函数是:
BOOL Usb_Init(HWND hwnd);
我试过:
[DllImport("UsbComm.dll", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool Usb_Init( out IntPtr hwnd);
我收到错误消息:
PInvoke signature does not match the unmanaged target signature.
如何调用上面的C++方法?
BOOL
在 <windef.h>
int
您需要在 C# 的导出声明中使用 int
。提示:值为0等于false
;其他都是 true
.
public static extern int Usb_Init(out IntPtr hwnd);
而且,您的调用约定也可能是错误的。尝试 CallingConvention
编辑:工作签名是
[DllImport("UsbComm.dll", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int Usb_Init(out IntPtr hwnd);
C++ 代码: 确保 Usb_Init 的定义应如下所示:
extern "C" __declspec(dllexport) BOOL __stdcall Usb_Init(HWND hwnd)
{
return TRUE;
}
C#代码:
using System;
using System.Runtime.InteropServices;
namespace Win32DllClient
{
class Program
{
[DllImport("UsbComm.dll", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
public static extern bool Usb_Init(out IntPtr hwnd);
static void Main(string[] args)
{
IntPtr hwnd = new IntPtr(0);
var ret = Usb_Init(out hwnd);
}
}
}
我看到问题中的代码有以下错误:
- C++代码使用
cdecl
,C#代码使用stdcall
。那不匹配。 - C++ 代码按值传递
HWND
。 C# 代码有一个IntPtr
作为out
参数传递。那不匹配。 DllImport
属性有多个虚假参数。
正确的 C# 声明是:
[DllImport("UsbComm.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool Usb_Init(IntPtr hwnd);
您可以将 ExactSpelling
设置为 true
,但我认为没有令人信服的理由这样做。如果您愿意,请随时添加。指定 CharSet
没有意义,因为不涉及文本。 SetLastError = true
可能是一个错误。根据我的判断,非托管函数调用 SetLastError
的可能性不大。我的期望是您在尝试消除错误时添加了 SetLastError = true
。