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);
        }
    }
}

我看到问题中的代码有以下错误:

  1. C++代码使用cdecl,C#代码使用stdcall。那不匹配。
  2. C++ 代码按值传递 HWND。 C# 代码有一个 IntPtr 作为 out 参数传递。那不匹配。
  3. DllImport 属性有多个虚假参数。

正确的 C# 声明是:

[DllImport("UsbComm.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool Usb_Init(IntPtr hwnd);

您可以将 ExactSpelling 设置为 true,但我认为没有令人信服的理由这样做。如果您愿意,请随时添加。指定 CharSet 没有意义,因为不涉及文本。 SetLastError = true 可能是一个错误。根据我的判断,非托管函数调用 SetLastError 的可能性不大。我的期望是您在尝试消除错误时添加了 SetLastError = true