如何编写我的 C++ 函数以便我可以从 C# 调用它?

Posted

技术标签:

【中文标题】如何编写我的 C++ 函数以便我可以从 C# 调用它?【英文标题】:How to write my C++ function so I can call it from C#? 【发布时间】:2012-03-13 12:54:09 【问题描述】:

我有 C++ 代码。该代码包含 Windows 移动 GPS 启用/禁用功能。我想从 C# 代码中调用该方法,这意味着当用户单击按钮时,C# 代码应该调用 C++ 代码。

这是启用 GPS 功能的 C++ 代码:

#include "cppdll.h"

void Adder::add()

// TODO: Add your control notification handler code here
  HANDLE hDrv = CreateFile(TEXT("FNC1:"), GENERIC_READ | GENERIC_WRITE,
                0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if (0 == DeviceIoControl(hDrv, IOCTL_WID_GPS_ON, NULL, 0, NULL, 0, NULL, NULL))
  
     RETAILMSG(1, (L"IOCTL_WID_RFID_ON Failed !! \r\n")); return;
  
     CloseHandle(hDrv);

 return (x+y);

这是头文件cppdll.h:

class __declspec(dllexport) Adder

  public:
   Adder();;
  ~Adder();;
 void add();
;

如何使用 C# 调用该函数?

请问有人可以帮我解决这个问题吗?

【问题讨论】:

【参考方案1】:

我给你举个例子。

您应该像这样声明要导出的 C++ 函数(假设最近的 MSVC 编译器):

extern "C"             //No name mangling
__declspec(dllexport)  //Tells the compiler to export the function
int                    //Function return type     
__cdecl                //Specifies calling convention, cdelc is default, 
                       //so this can be omitted 
test(int number)
    return number + 1;

并将您的 C++ 项目编译为 dll 库。将项目目标扩展名设置为 .dll,将配置类型设置为动态库 (.dll)。

然后,在 C# 中声明:

public static class NativeTest

    private const string DllFilePath = @"c:\pathto\mydllfile.dll";

    [DllImport(DllFilePath , CallingConvention = CallingConvention.Cdecl)]
    private extern static int test(int number);

    public static int Test(int number)
    
        return test(number);
    

然后你可以调用你的 C++ 测试函数,正如你所期望的那样。请注意,一旦您想要传递字符串、数组、指针等,它可能会变得有点棘手。例如,请参阅this SO question。

【讨论】:

我仍然会这样做:#define EXPORT __declspec(dllexport) @Quandary 当然,不管你的船是什么。我喜欢明确指定调用约定,所以我需要一个更高级的宏来获取类型参数,而且我通常会尽量避免更高级的宏,我相信你知道 - 邪恶. 感谢您的回复。我已经编辑了代码。它给出了错误。我也更改了配置。请帮我。 \GpsCppToDll.cpp(2) : warning C4627: '#include "GpsCppToDll.h"': skipped when looking for precompiled header use 1> Add directive to 'stdafx.h' or rebuild precompiled header 1>.\GpsCppToDll.cpp(15) : fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source? 看起来您在创建项目时选择了使用预编译头文件,然后忘记将其包含在您的 .cpp 文件之一中。您可以在 GpsCppToDll .cpp 文件中添加一个#include stdafx.h(在最顶部)。 你能不能看看这个问题***.com/questions/9410197/cant-find-pinvoke-dll-bug

以上是关于如何编写我的 C++ 函数以便我可以从 C# 调用它?的主要内容,如果未能解决你的问题,请参考以下文章

在 Mono 中将 C++ 暴露给 C#:函数的无效转换?

从 C# 中的 C++ 代码中获取对象功能

如何从 c++ 项目中调用用 c# 创建的 dll 文件? [复制]

将状态更新从 C++ 中的函数发送到 C#

如何中断从 c# interop 调用的 c++ 代码

如何从 C++ 后台任务(Windows 通用应用程序)调用 C# 函数?