Siy*_*ion 7 c# c++ clr interop marshalling
所以我所拥有的是*.dll中包含的C++ API,我想使用C#应用程序来调用API中的方法.
到目前为止,我已经创建了一个包含本机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);
}
}
Run Code Online (Sandbox Code Playgroud)
.
// ManagedBridge.cpp
#include <ManagedBridge.h>
int Bridge::bridge_test(void)
{
return test();
}
int Bridge::bridge_test2(api_struct* temp)
{
return test2(temp);
}
Run Code Online (Sandbox Code Playgroud)
我还有一个C#应用程序,它引用了C++/CLR"Bridge.dll",然后使用其中包含的方法.我有很多问题:
编辑:好的,所以我现在有了基础工作,感谢下面的回复,但是我的结构(在这个例子中称之为"api_struct2")在C++本机代码中同时具有本机枚举和联合,如下所示:
typedef struct
{
enum_type1 eEnumExample;
union
{
long lData;
int iData;
unsigned char ucArray[128];
char *cString;
void *pvoid;
} uData;
} api_struct2;
Run Code Online (Sandbox Code Playgroud)
我想我已经想出如何让enum工作; 我已经在托管代码中重新声明它并执行"native_enum test = static_cast(eEnumExample)"将托管版本切换为本机版本.
然而,工会让我难倒,我不确定如何攻击它..想法有人吗?
是的,您正在通过引用传递非托管结构。这对于 C# 程序来说是一个问题,指针与垃圾收集非常不兼容。不考虑它可能也没有结构声明的事实。
您可以通过声明结构的托管版本来解决它:
public value struct managed_api_struct {
// Members...
};
Run Code Online (Sandbox Code Playgroud)
现在您可以将该方法声明为
int bridge_test2(managed_api_struct temp); // pass by value
Run Code Online (Sandbox Code Playgroud)
或者
int bridge_test2(managed_api_struct% temp); // pass by reference
Run Code Online (Sandbox Code Playgroud)
如果结构具有超过 4 个字段(~16 字节),请选择后者。该方法需要将结构体成员一一复制到非托管 api_struct 中并调用非托管类方法。不幸的是,这是必要的,因为托管结构的内存布局是不可预测的。
这一切都非常机械,您可能会从 SWIG获得帮助。我自己没有使用过它,不确定它是否足够智能来处理传递的结构。
一种完全不同的方法是通过为包装类提供一个构造函数和/或属性来让您构建 api_struct 的内容,从而使包装类更清晰。或者您可以为该结构声明一个包装器引用类,就像在托管代码中一样。
| 归档时间: |
|
| 查看次数: |
2483 次 |
| 最近记录: |