首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Marshal to std::string从System::String^成员的struct句柄

Marshal to std::string从System::String^成员的struct句柄
EN

Stack Overflow用户
提问于 2015-05-29 12:39:20
回答 1查看 771关注 0票数 3

我试图从系统::String^封送至std::string。

通常,这可以通过marshal_as<T>模板来完成,即

代码语言:javascript
复制
System::String ^managedString = "test";
std::string stdString = marshal_as<std::string>(managedString);

但是,如果字符串^是通过引用访问的结构的一部分,则为

代码语言:javascript
复制
value struct SomeStruct {
    String ^managedString;
};

auto structHandle = gcnew SomeStruct();
structHandle->managedString = "test";
std::string stdString = marshal_as<std::string>(structHandle->managedString);

编译器将抛出以下错误

错误C2665:'msclr::interop::marshal_as‘:三个重载都不能转换所有参数类型

但是,如果结构不是句柄,而是实际的结构,则可以正常工作。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-05-29 13:27:34

代码语言:javascript
复制
   auto structHandle = gcnew SomeStruct();

这就是问题开始的地方。structHandle引用指向SomeStruct的装箱副本。它需要装箱,因为SomeStruct是一个值类型,结构的副本存储在GC堆上。

您试图使用的marshal_as<>重载的签名是:

代码语言:javascript
复制
   marshal_as<std::string,System::String^>(System::String ^const &)

const&是问题所在,您无法获得对成员的非托管引用,其地址不稳定(不是const),因为垃圾收集器可以在marshal_as<>执行时移动对象。当marshal_as现在取消不再存在的对象时,这将导致灾难。

解决方法是在尝试转换引用之前将引用从装箱对象中复制出来:

代码语言:javascript
复制
   structHandle->managedString = "test";
   String^ refCopy = structHandle->managedString;
   std::string stdString = marshal_as<std::string>(refCopy);   // fine

但这只是针对代码中真正的问题的一次黑客攻击。值类型的存在是为了提高代码效率,允许将结构存储在堆栈帧或CPU寄存器上。就像原生C++对象一样。你用拳击的方法把这个优势丢掉了。换句话说,如果您不打算将value struct视为一个值,那么声明它就没有任何意义了。正确地使用它进行正确的修复:

代码语言:javascript
复制
    SomeStruct value;
    value.managedString = "test";
    auto result = marshal_as<std::string>(value.managedString);  // fine

或者,如果错误地在函数参数上使用^获得引用,则重写到:

代码语言:javascript
复制
    void SomeFunction(SomeStruct% arg) {
        auto nativeString = marshal_as<std::string>(arg.managedString);
        '' etc..
    }

注意使用%而不是^通过引用传递变量。但是不要这样做,值类型的要点是复制值比取消引用指针来获得值要便宜。确保您的值类型不太大,它不应该有超过4个字段。如果它更大,那么您应该使用引用类型。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30529869

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档