c# - 向 C# 公开 C++ API

标签 c# c++ interop clr marshalling

所以我有一个包含在 *.dll 中的 C++ API,我想使用 C# 应用程序调用 API 中的方法。

到目前为止,我已经创建了一个包含 native C++ API 的 C++/CLR 项目,并设法创建了一个类似于以下内容的“桥接”类:

// ManagedBridge.h
#include <CoreAPI.h>
using namespace __CORE_API;

namespace ManagedAPIWrapper
{
    public ref class Bridge
    {
        public:
            int             bridge_test(void);
            int             bridge_test2(api_struct* temp);
    }
}

.

// ManagedBridge.cpp
#include <ManagedBridge.h>

int Bridge::bridge_test(void)
{
    return test();
}

int Bridge::bridge_test2(api_struct* temp)
{
    return test2(temp);
}

我还有一个 C# 应用程序,它引用了 C++/CLR“Bridge.dll”,然后使用其中包含的方法。我对此有很多问题:

  1. 我不知道如何在 C# 程序中调用 bridge_test2,因为它不知道 api_struct 实际上是什么。我知道我需要在某处编码对象,但我是在 C# 程序中还是在 C++/CLR 桥中进行编码?
  2. 这似乎是一种非常公开 API 中所有方法的冗长方式,难道没有一种更简单的方法我错过了吗? (这不使用 P/Invoke!)

编辑: 好的,由于下面的回复,我现在已经掌握了基础知识,但是我的结构(在本例中称为“api_struct2”)在C++ native 代码,如下所示:

typedef struct
{
    enum_type1  eEnumExample;
    union
    {
            long        lData;
            int     iData;
            unsigned char   ucArray[128];
            char        *cString;
            void        *pvoid;
    } uData;
} api_struct2;

我想我已经弄清楚如何让枚举工作;我已经在托管代码中重新声明了它,并且正在执行“native_enum test = static_cast(eEnumExample)”以将托管版本切换到 native 。

但是 union 让我难住了,我真的不确定如何攻击它。有人有想法吗?

最佳答案

是的,您正在通过引用传递非托管结构。这是 C# 程序的问题,指针与垃圾回收非常不兼容。不包括它可能也没有结构声明的事实。

您可以通过声明结构的托管版本来解决它:

public value struct managed_api_struct {
  // Members...
};

现在您可以将方法声明为

int bridge_test2(managed_api_struct temp);   // pass by value

int bridge_test2(managed_api_struct% temp);  // pass by reference

如果结构有超过 4 个字段(~16 字节),请选择后者。该方法需要将结构成员一个接一个地复制到非托管 api_struct 中并调用非托管类方法。不幸的是,这是必要的,因为托管结构的内存布局是不可预测的。

这一切都非常机械化,您可能会得到帮助 from SWIG .我自己没用过,不确定它是否足够智能来处理传递的结构。

一种完全不同的方法是通过为包装类提供一个构造函数和/或允许您构建 api_struct 内容的属性来使包装类更清晰。或者您可以为该结构声明一个包装器 ref 类,就像您在托管代码中所做的那样。

关于c# - 向 C# 公开 C++ API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2606216/

相关文章:

c++ - 是否可以在全局范围内构造一个临时变量?

c++ - 如何在窗口周围绘制矩形而不覆盖 win32 中的标题栏

c++ - std::vector 的 push_back() 导致奇怪的编译时错误消息

c# - 在我的 .NET 应用程序中添加一个函数作为另一个 .NET 应用程序中的事件处理程序

c# - Linq 代码不返回正确的记录

c# - WPF 自定义弹出窗口

c# - 实习字符串是否有助于解析器的性能?

c# - 如何将 SQL 查询应用于 C# 数据表/数据集?

windows - 何时以及为何使用 CoLoadLibrary?

c# - 我应该使用 ReAllocHGlobal 还是 FreeHGlobal/AllocHGlobal?