【问题标题】:Pass objects from referenced managed dll to a C++/CLI wrapper将对象从引用的托管 dll 传递到 C++/CLI 包装器
【发布时间】:2014-02-04 16:23:00
【问题描述】:

所以,我正在编写一个 C++/CLI 包装器,我希望它与来自引用的托管 (C#) dll 的对象进行交互。更具体地说,在我的 C++/CLI 项目中,我希望有这样的类:

public ref class MyClass
{
    public:
        void InputPoints(array<Point3d^>^ ptsIn);
};

其中,“Point3d”是引用的托管 dll 中的一个对象 - 称之为“MyGeometryDLL.dll”。这编译没有任何问题,但是当我在 C# 项目中使用包装器(也引用“MyGeometryDLL.dll”)时,我无法将 Point3d 直接传递给包装器,即智能感知检测到:

void MyClass.InputPoints(ValueType[] ptsIn);

如何将 Point3d 直接传递给包装器?

【问题讨论】:

  • 问题出在 Point3d 上,它不是托管类型。你需要声明,比如说,public value class Point3d { /* ... */ };
  • 嗨,汉斯,谢谢!但是,现在我的 C# 项目期望返回类型为“MyWrapper.Point3d[]”。我仍然不清楚如何将其转换为 MyGeometryDLL.Point3d。
  • 如果你做public value class,那是一个值类型,所以你需要删除Point3d上的^array&lt;Point3d&gt;^。如果您希望它成为引用类型,请使用public ref class,并保留^
  • 您不能将托管结构转换为非托管结构,它们通常没有相同的布局。您可以使用 Marshal::StructureToPtr() 进行转换,但这对于简单的结构来说往往是过度的。仅分配结构成员是更简单的方法。这确实倾向于调用“真的???”感叹。对真的。结构布局是一个非常讨厌的实现细节。
  • 顺便说一句,大卫确实提出了一个有效点,如果 Point3d 实际上是一个托管结构,那么你必须省略 ^ 帽子。它应该只用于引用类型。

标签: dll c++-cli wrapper


【解决方案1】:

所以 Point3d 类已经在 C# DLL 中定义了,对吗?在那种情况下,我认为这可能是克拉的问题。

如果它在 C# 中声明为 public struct Point3d,那么它是值类型,而不是引用类型。这意味着无论何时在 C++/CLI 中使用它,都不会使用^,也不会调用gcnew。如果是这种情况,那么您需要将方法声明更改为:

void InputPoints(array<Point3d>^ ptsIn); // No carat on Point3d

C# 将其视为ValueType[] 的原因是因为Point3d^ 在 C++/CLI 中是合法类型,但在 C# 中不存在。一般的ValueType 是最接近的,所以这就是C# 所看到的。

【讨论】:

    猜你喜欢
    • 2018-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-01
    相关资源
    最近更新 更多