【问题标题】:How to marshal following native C++ objects to C++/CLI?如何将本机 C++ 对象编组到 C++/CLI?
【发布时间】:2012-02-02 01:24:28
【问题描述】:

我对如何将下面提到的 C++ 对象编组为 c++/CLI 有点困惑。你能给我一些想法吗?

原生 C++ 类

class HeaderMessage {
    double timestamp;
    string ric_code;
}

class TradeMessage {
   double price;
   int size;
}

 class RFARecord
 {
public:
    RFARecord();
    HeaderMessage * hMsg;
    list<TradeMessage *> qMsgs;
 };

我的 C++/CLI 类如下所示

    public ref class RFARecordRef
{
public:
    RFARecordRef();
    RFARecordRef(RFARecord *record);
    HeaderMessageRef hMsg;
    List<TradeMessageRef> tMsgs;
private:
    RFARecord *record;
};

    ref class HeaderMessageRef
    {
    private:
        HeaderMessage *hMsg;
    public:
        HeaderMessageRef(void);
    };

    ref class TradeMessageRef
    {
    private:
        TradeMessage *tMsg;
    public:
        TradeMessageRef(void);
    };

我不确定我的方法是否正确。

我从文本文件中读取数据并以 RFARecords 的形式将这些数据传输到我的 C# 程序。

将以上数据对象包装或编组到 C++/CLI 的正确方法是什么,然后我的 C# 程序可以使用这些对象。

提前致谢。

问候, 阿洛克

【问题讨论】:

  • 我已经阅读了上面的帖子。它最初帮助我设置了包装器。我已经通过了这一点。我能够将我的本机类包装在运行良好的 CPP/CLI 层中。我现在的问题是正确编组数据。基本问题是结构列表的编组(这些结构包含基本的 adta 类型)

标签: interop c++-cli marshalling


【解决方案1】:

如果我理解正确的话。您最大的任务是将 c++ 字符串中的字符串编组到 System::String^ 对象中。

您要做的是在 C++/CLI 类中声明一个返回类型 System::String^ 的方法,如下所示:

System::String^ get_str_from_cpp()
{
   std::string str = ptr_to_native_cpp_class->get_str();
   System::String^ ret_str = std_str2sys_str(str);
   return ret_str;
}

std_str2sys_str 方法看起来像这样。

static System::String^ std_str2sys_str(std::string std_str)
{
   System::String^ sys_str = gcnew System::String(std_str.c_str());
   return sys_str;
}

如果你愿意,当然可以使用 char*。

“ptr_to_native_cpp_class”变量应该是一个类变量,指向您的本机 c++ 类的实例。看来你已经有了这些。

还有一些方法可以将 System::String^ 编组为网络上的 std::string 或 char*。希望这个例子有所帮助。不过,您不必担心编组基本类型(如 int 或 bool),您可以直接将它们从 C++/CLI 层返回到 C#。

回答将结构编组到 C++/CLI 的问题;我认为没有办法自动编组整个自定义结构,即使它完全由基本类型组成。我在我的代码中所做的只是编写一个包装器对象,它对每个数据成员都有特定的 get 方法,如下所示:

//Native C++ class
class data_container
{
public:
   int var1;
   int var2;
}

//C++/CLI class
public ref class cli_data_container
{
public:
   get_var1() {return data_ptr->var1;}
   get_var2() {return data_ptr->var2;}
private:
   data_container* data_ptr;
};

如果有一种自动的方法可以做到这一点,那就太好了,但是去年夏天我们有一个实习生为我们制作了几十个实用程序类的这些接口,他们完成了工作。

【讨论】:

  • 不要自己编写std_str2sys_str函数,使用Visual C++提供的marshal_as&lt;&gt;模板。
  • @Ben,我想是的。这在 VS2005 中可用,还是仅在 08 中可用?顺便说一句,这里是 CodeProject 的链接,其中列出了 marshal_as 的用法codeproject.com/KB/mcpp/OrcasMarshalAs.aspx
  • 如果VS2005没有自带,相信可以下载添加。还有一个扩展实现 here 可以处理更多类型。
  • 感谢本和伊恩。以上信息有很大帮助。但我对编组基本字符串类型没有问题。我正在使用自己的模板将本机字符串转换为 CLI 稍后的字符串。我在编组由 HeaderMessage 结构和贸易消息结构列表组成的 RFARecord 类时遇到问题。 (这些结构仅包含基本类型)。您能否进一步了解编组 RFARecord 结构?提前致谢。
  • @Alok,如果您希望在 C# 中创建一个结构数组,那么您将不得不创建一个包装器数组并添加将指针设置为本机的逻辑c++ 为数组中的每个成员正确键入。
猜你喜欢
  • 2011-04-30
  • 1970-01-01
  • 1970-01-01
  • 2016-09-20
  • 2016-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-01
相关资源
最近更新 更多