gpt4 book ai didi

c# - 使用 C# 中的 C++/CLI 结构

转载 作者:行者123 更新时间:2023-12-02 04:57:28 25 4
gpt4 key购买 nike

让我开始另一个问题,因为虽然我看到了很多类似的问题,但没有人真正谈论这方面...我有一个 C++ DLL(没有源代码,但 .lib 和 .h),并且我编写了必要的托管包装器。这没有问题,问题是关于原始 C++ 代码中定义的结构体和枚举,它们有很多,都需要暴露给 C# 代码。教程和示例通常使用简单的数据类型,例如 float 和字符串,而不是复杂数据结构的现实场景。

我的托管 C++/CLI 包装器使用 DLL 的 .h 头文件中的非托管结构。我包装的类成员函数一直使用它们。因此,我需要在 C# 代码中使用相同的结构,传递它们并从 C++ 代码接收。很明显,我无法避免在 C# 中重新定义所有这些,但即使如此,使用它们也是有问题的。让我们举一个例子:非托管代码中的函数使用的简单结构:

typedef struct INFO {
...
} INFO;

int GetInfo(INFO& out_Info);

我在 C++/CLI 包装器代码中声明了相同的结构:

public ref struct INFO_WRAP {
...
};

int GetInfo(INFO_WRAP out_Info);

包装器代码中的实现尝试将此新结构转换为原始结构,以使用旧的非托管代码:

int Namespace::Wrapper::GetInfo(INFO_WRAP out_Info) {
pin_ptr<INFO> pin_out_Info = out_Info;
return self->GetInfo(*(::INFO*)pin_out_Info);
}

但这不会编译(无法在结构之间进行转换,并且找不到合适的转换)。

有没有一种解决方案不涉及创建新的数据结构和手动来回复制所有结构成员?不仅因为额外的工作和时间,而且结构真的很多。

最佳答案

  public ref struct INFO_WRAP

您没有声明结构,这是 C# 术语中的类。古怪的 C++ 实现细节,C++ 结构只是一个具有所有成员 public 的类。您需要在 C++/CLI 中使用值结构来声明 C# 结构的等效项。

  int Namespace::Wrapper::GetInfo(INFO_WRAP out_Info)

这也是错误的,因为 INFO_WRAP 实际上是一个引用类型,因此您必须始终使用 ^ 帽子来声明它。或者用 % 通过引用传递它,这肯定是这里的意图。

<小时/>

基本障碍已排除,您所要求的内容并未得到直接支持。托管编译器不允许对托管结构的布局做出任何假设。无论如何,当你尝试时它会吠叫。有一个很好的理由,那就是 just not that predictable 。布局是一个强大的运行时实现细节,如果代码在不同的运行时运行,布局可能会发生变化。就像 32 位与 64 位一样,可能在其中一种中有效,但在另一种中无效。正如乔恩发现的那样。

逐一复制字段总是有效并且性能足够。只是不是程序员喜欢维护的代码。您可以要求框架为您做这件事,调用Marshal::PtrToStructure()或 StructureToPtr()。

<小时/>

作弊是可能的,并且在您编写 C++/CLI 代码时肯定会考虑到这一点。毕竟,该语言的重点是使互操作更快。您只会使保修失效,您必须在您打算支持的任何平台上彻底测试代码。一个简单的例子:

public value struct Managed {
int member1;
int member2;
};

struct Native {
int member1;
int member2;
};

void GetInfo(Managed% info) {
Native n = { 1, 2 };
pin_ptr<Managed> pinfo = &info;
memcpy(pinfo, &n, sizeof(n));
}

With 工作得很好并且可以在任何平台上按预期执行,结构很简单。当结构不简单或者你修改了 Native 而忘记修改 Managed 时,就会付出惨重的代价,堆栈和 GC 堆损坏是非常令人不快的事故,而且很难调试。

关于c# - 使用 C# 中的 C++/CLI 结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35912787/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com