C++ 函数到 C#
Posted
技术标签:
【中文标题】C++ 函数到 C#【英文标题】:C++ function to C# 【发布时间】:2015-02-03 05:27:43 【问题描述】:我对 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 签名与非托管目标签名不匹配。
如何调用上述C++方法?
【问题讨论】:
可能是respective sizes of the bool 可能的 c++ 名称修改 @MickyDuncan 如果是这样,那么错误会有所不同。该错误会报告找不到该函数。 @DavidHeffernan 是的。谢谢你 【参考方案1】:我在问题的代码中看到以下错误:
-
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
。
【讨论】:
【参考方案2】:BOOL
在<windef.h>
中定义为int
您需要在 C# 的导出声明中使用 int
。提醒:值为0等于false
;其他的都是true
。
public static extern int Usb_Init(out IntPtr hwnd);
而且,您的调用约定也可能是错误的。尝试CallingConvention
的每个枚举
EDIT:工作签名是
[DllImport("UsbComm.dll", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
public static extern int Usb_Init(out IntPtr hwnd);
【讨论】:
我试过 DllImport("UsbComm.dll")] public static extern int Usb_Init(out IntPtr hwnd);也称为方法 IntPtr hwnd = new IntPtr(0); var res = Usb_Init(out hwnd);出现签名不匹配错误 谢谢...你拯救了我的一天 [DllImport("UsbComm.dll", SetLastError = true, CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern int Usb_Init(out IntPtr hwnd); 您已接受此答案,但它不正确。hwnd
参数传递不正确。并且没有必要将返回类型设为int
。您可以在 C# 中使用 bool
,它被编组为 Windows BOOL
类型。
这是一个新问题。而且相当棘手。您可能需要包含更多信息。您不能在 cmets 中提问。但是,这里已经提出了这个问题:***.com/questions/28293025/… 我确实认为您需要退后一步,阅读 SO 站点的帮助内容。如果您对如何提出好的问题有更清楚的了解,您将从该网站中获得更多收获。【参考方案3】:
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++ 函数到 C#的主要内容,如果未能解决你的问题,请参考以下文章
如何将委托或函数指针从 C# 传递到 C++ 并使用 InternalCall 调用它
如何使用 p/invoke 终止从 C# 调用的 C++ 函数