首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++:原生于托管字符串转换问题(可能是字符集)?

问C++:原生于托管字符串转换问题(可能是字符集)?
EN

Stack Overflow用户
提问于 2018-11-26 22:32:52
回答 1查看 163关注 0票数 0

在正确的字符集中返回一个本机字符串有问题。我将从字符串转换为wstring到LPCWSTR,以将其传递给托管。对于字符串到宽字符串,s2ws法生成一个非常小的字符串返回,因为它似乎停止在我的第一个准结束符(在托管中),即';‘。所以,在你提到s2ws之前,我已经试过了,但没有结果。

串的东西:

代码语言:javascript
复制
    char target[1024];
    sprintf_s(target, 1024, "%s %s%s%s",
            mac,
            " (",
            pWLanBssList->wlanBssEntries[t].dot11Ssid.ucSSID,
            ");");
    std::string targetString = std::string(target);
    targetWString.append(targetString.begin(), targetString.end());

稍后的字符串内容:

代码语言:javascript
复制
std::wstring returnWString = L"";
returnWString.append(SomeMthod().c_str());
//wprintf_s(returnWString.c_str()); // Works - Data is in the string.
LPCWSTR returnLpcuwstr = returnWString.c_str();
return returnLpcuwstr;

我如何知道这是一个字符集/编码问题?好的,当LPCWSTR返回给managed,并且我使用Marshal对Unicode字符串时,我会得到一个空/空字符的墙。当我在ANSI中尝试时,这就是我所得到的(缩小了可读性的大小/规模):

ÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝ

s2ws方法应该解决ANSI/UNICODE噩梦,即std::string->std:wstring,但这使得返回的时间太短--比应该的要短得多--但是没有解决实际的字符集问题。

结果(对ANSI,同样-ÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝÝ

当我签入本机时,S显示在导出方法中进行LPCWSTR转换之前字符串是有效的/良好的;因此,我需要理解:

  1. 有什么方法可以告诉我字符的字节大小吗?(我认为这是一个8字节与16字节的场景?)
  2. 由于wprintf_s在宽字符串上工作,所以我根据LPCWSTR检查了它,并打印了相同的(预期的)数据;因此,问题似乎不在LPCWSTR的.ctor()中。然而,我想再检查一遍我的数学:我是正确的吗?
  3. 由于本机中的所有内容都告诉我字符串是好的,我如何检查它的字符集(在本机中)?

返回本身是大约8行文本,使用了一个分隔符“;”,这样我就可以在托管中拆分字符串并使用它执行魔术。唯一的问题是将字符串呈现为托管中的有效字符串,其中包含正确的字符。

我觉得,也许,我错过了一些显而易见的东西,但我不知道它是什么,我只是需要一双新的眼睛来告诉我,我在哪里和如何在生活中失败。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-11-26 22:57:34

代码语言:javascript
复制
LPCWSTR returnLpcuwstr = returnWString.c_str();
return returnLpcuwstr;

这是返回一个指向数据的指针,当return超出范围时,数据将在returnWString之后立即释放。返回的指针在接收方甚至可以使用它之前是无效的。这是未定义的行为。

要执行您正在尝试的操作,您必须返回指向动态分配内存的指针,然后接收方在使用该内存时必须释放该内存。

假设“托管”是指.NET,那么.NET的封送处理程序使用CoTaskMemFree()释放非托管内存,因此如果使用默认封送处理,返回的指针必须指向使用CoTaskMemAlloc()或等效(例如,SysAllocString...())分配的内存。

否则,如果不使用默认封送处理(即手动调用Marshal.PtrToStringUni() ),则必须让.NET代码将内存指针传递回C++代码,这样它才能正确释放内存。然后,您的C++代码可以任意分配内存(只要它仍然是动态分配的,这样它就可以在函数返回之后存活下来)。

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

https://stackoverflow.com/questions/53490128

复制
相关文章

相似问题

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