C++/CLI C#字符串转为C++字符串正确写法

本文探讨了C#与C++互操作时,使用Marshal.StringToHGlobalAnsi可能导致的内存泄漏问题,并提供了一个解决方案。通过引入msclr库的marshal_as方法,创建了两个函数ToManaged和ToUnmanaged,实现了字符串的无内存泄漏转换。这两个函数确保了内存的正确管理,避免了内存泄漏的发生。
摘要由CSDN通过智能技术生成

常规来说,会调用C#中Runtime::InteropServices::Marshal下的函数去进行转换,如下,使用了其中的一个函数,

char * ch = (char*)(void*)Runtime::InteropServices::Marshal::StringToHGlobalAnsi(managedString);
std::string myString = std::string(ch);

但是这个API会造成内存泄露,网上搜索,StackOverflow上有人遇到相同问题,点击这里,给出的答案如下,

#include <msclr\marshal.h>

System::String^ ToManaged(const wchar_t* unmanagedString)
{
    return msclr::interop::marshal_as<System::String^>(unmanagedString);
}

gcroot<msclr::interop::marshal_context^> context;

const wchar_t* ToUnmanaged(System::String^ managedString)
{        
    msclr::interop::marshal_context^ unpacked = context;

    if (unpacked != nullptr)
        delete unpacked;

    context = gcnew msclr::interop::marshal_context();

    return context->marshal_as<const wchar_t*>(managedString);
}

该答者提供了互相转换的函数,经过测试,确实没有内存泄露。

第二个函数ToUnmanaged()看起来有点迷惑,其原理是使用全局变量context,让它来执行转换,转换完之后内存并没有释放,等到第二次再调用这个函数时才去释放上一次的内存。

如果C++这边不是使用wchar_t*,而是使用char*,那么就改成如下,
 

gcroot<msclr::interop::marshal_context^> context;

const char* ToUnmanaged(System::String^ managedString)
{        
    msclr::interop::marshal_context^ unpacked = context;

    if (unpacked != nullptr)
        delete unpacked;

    context = gcnew msclr::interop::marshal_context();

    return context->marshal_as<const char*>(managedString);
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值