c++托管到非托管转换
c++ Managed to unmanaged conversions
我已经做了许多托管包装器,它们处理包装未经管理的代码以用于托管,但没有太多相反的方法。
我正在运行的一个实验涉及使用托管代码来查找目录并以std向量返回它们。长话短说,我把下面的例子搞砸了,发现了一个问题。
#include "Helper.h"
#include <msclr/marshal.h>
#include <msclr/marshal_cppstd.h>
using namespace msclr::interop;
using namespace System;
namespace CLIWrapper {
std::vector<std::string> Helper::GetDirs(const char* root)
{
std::vector<std::string> rval;
String^ path = gcnew System::String(root);
array<String^,1>^ dirs = System::IO::Directory::GetDirectories(path);
for (int i=0; i < dirs->Length; i++)
{
//this fails
std::string nativeString1(marshal_as<std::string>(dirs[i]));
//this fails as well
std::string nativeString2(marshal_as<std::string>((String ^ const)dirs[i]));
// this works
String ^mStr = dirs[i];
std::string nativeString(marshal_as<std::string>(mStr));
rval.push_back(nativeString);
}
return rval;
}
}
"nativeString1"answers"nativeString 2"的失败为:错误C2665:"msclr::interop::marshali_as":3个重载都无法转换所有参数类型
"nativeString2"使用常量,因为如果查看错误的详细信息,它会列在封送处理_as的一个签名中。
问题是,为什么"nativeString1"转换失败,但"nativeString"有效?我的眼睛拒绝注意到什么?
在它出现在响应线程中之前:是的,我意识到这不是"最佳"解决方案,它不是独立于平台的,等等。我正在努力关注这个特定的错误。
这是由Justin在评论中提到的签名引起的,也就是
template <> inline std::string marshal_as(System::String^ const & _from_obj)
这样做真的很糟糕。这是对指向Ssytem::String
的跟踪指针的非跟踪引用。因为它是const
引用,所以它可以绑定到临时引用,但是因为它是非跟踪引用,所以不能绑定到垃圾收集堆内的内存位置,因为gc堆上的对象可以四处移动。
您应该已经能够通过身份转换来解决这个问题,根据C++标准,身份转换会创建一个相同类型的临时。临时不在gc堆中,所以是的一切都可以。
不幸的是,存在一些与身份转换相关的编译器错误,因此,您实际上并没有得到临时的。
Justin转换为跟踪引用并返回到跟踪指针是创建临时指针的另一种方式。不幸的是,他的回答中包含了一些关于引用计数的胡言乱语。NET对象没有被引用计数。
最重要的是,首先没有理由通过const引用传递该参数。跟踪指针很小,很容易复制。这是marshal_as
作者的一个风格错误,几乎是一个bug。您可以将头文件更改为
template <> inline std::string marshal_as(System::String^ const _from_obj)
而不破坏实现。
另一个解决方案是使用跟踪参考,如
template <> inline std::string marshal_as(System::String^ const % _from_obj)
但同样,没有意义,因为传递价值是如此便宜。
编译器不认为dirs[i]
是对字符串的常量引用(这也让我感到惊讶)。但是,您可以通过使用%运算符获得对该值的临时常量引用,而无需创建新的字符串句柄,这将增加dirs[i]
:处字符串的引用计数
// this works as well
auto nativeString1(marshal_as<std::string>(%*dirs[i]));
- 防止主数据类型C++的隐式转换
- 模板参数替换失败,并且未完成隐式转换
- 努力将整数转换为链表。不知道我在这里做错了什么
- HEX值到wchar_t字符(UTF-8)的转换
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将 Qvector<uint8_t> 转换为 QString
- 如何在cuSparse中使用cusparseXcoo2csr从coo转换为csc
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 在c++中使用nlohmann从类到json的转换
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- 复制列表初始化的隐式转换的等级是多少
- 正在将指针转换为范围
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 是否可以从int转换为enum类类型
- 了解 GLM- openGL 中的相机转换
- 将无符号char*转换为std::istream*C++