MFC Unicode和多字符集中一个很恶心的问题

Walle_Oyq 2013-11-25 03:43:09
我使用了一个动态链接库。这个库是在多字符集环境下写的(唉,都是99年的老古董库了。)里面有一个函数

HRESULT DSStream_SaveToBmpFile(int iCardID, LPCTSTR szFileName);

而我用的编译器是VS2012,默认为UNICODE,然后为了能够使用这个库,在各位大神(说不定您上次还来回复过)的提示之下,我将整个库的头文件修改了,上面的函数被改为:

HRESULT DSStream_SaveToBmpFile(int iCardID, LPCSTR szFileName);

也就是将第二个参数由LPCTSTR 改成了LPCSTR,之所以这么改,是因为不修改它的话,编译会出错。

OK,然后我调用一个函数区得到一个LPCSTR 类型的变量:LPCSTR name = GetName();
得到name(假定得到的字符串是C:\\Image\\Image1245.bmp)后,我开始调用整个函数:

DSStream_SaveToBmpFile(name);

BUT,当函数执行完毕之后,name的值被修改成了一串无意义的字符“铪铪铪铪铪铪铪铪铪铪铪铪铪铪铪铪”

然后调用当然就出错了。

但是如果直接这么调用 :DSStream_SaveToBmpFile("12345.bmp");

函数会调用成功,在当前的工程目录下会找到该图片。
请问这是怎么了?我不明白为啥这个值会被修改。每次看到那个 哈哈哈哈 我就觉得它在笑我。
...全文
228 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
shen_wei 2013-11-26
  • 打赏
  • 举报
回复
要想不出错,那就统一字符集,修改也不难的!!
davidyu720 2013-11-26
  • 打赏
  • 举报
回复
程序员应该随时关注自己写的代码用到的内存区的分配情况、生命周期。
Walle_Oyq 2013-11-26
  • 打赏
  • 举报
回复
引用 11 楼 baichi4141 的回复:
楼主的问题不在于UNICODE字符集和多字节字符集,而在于使用了已经失效的内存。 LPCSTR name = GetName();这是以前C语言比较流行的写法,返回一个生存期不确定的局部内存指针,在函数返回之后这块内存尚未被覆盖,因此这个指针暂时是有效的。但当楼主以为这东西很稳定于是下面的代码不管它去干别的了,这块内存就可能被其他函数覆盖掉。 使用std::string s = GetName();的原因是这是std::string的一种构造方式,直接将该指针指向的内存字符串复制到了s自己管理的专用内存中,于是就可以在其他地方随意使用了。
哦,原来是这样啊,我说怎么用std:string就好了呢。谢谢啊!
Walle_Oyq 2013-11-26
  • 打赏
  • 举报
回复
引用 9 楼 Sandrer 的回复:
首先我觉得楼主还没搞清楚宽字符集与多字节字符集的区别 本来人家提供的函数就是 UNICODE 宽字符集的 你还多此一举的改来改去 UNICODE 为宽字符集,对应的字符类型为 wchar_t char 类型的才是多字节字符集 看到有什么不一样吗?宽字符集多了个 w 和 t 相对的 LPCTSTR 与 LPCSTR,哪个为 UNICODE?
不是我不知道,而是这个库写的有问题:头文件声明的是LPCTSTR ,而动态链接库导出的函数声明里面却是 const char *,所以如果直接使用,在UNICODE环境下编译都通过不了,这个问题上次发帖的时候好多版主都来讨论搞了个把星期才弄好。只能说写这个库的人比较2。声明和实现弄的不一致。
路马 2013-11-25
  • 打赏
  • 举报
回复
楼上说的太好了,我也一般用std::string,觉得返回值用LPCSTR好容易出错!
baichi4141 2013-11-25
  • 打赏
  • 举报
回复
楼主的问题不在于UNICODE字符集和多字节字符集,而在于使用了已经失效的内存。 LPCSTR name = GetName();这是以前C语言比较流行的写法,返回一个生存期不确定的局部内存指针,在函数返回之后这块内存尚未被覆盖,因此这个指针暂时是有效的。但当楼主以为这东西很稳定于是下面的代码不管它去干别的了,这块内存就可能被其他函数覆盖掉。 使用std::string s = GetName();的原因是这是std::string的一种构造方式,直接将该指针指向的内存字符串复制到了s自己管理的专用内存中,于是就可以在其他地方随意使用了。
baichi4141 2013-11-25
  • 打赏
  • 举报
回复
引用 9 楼 Sandrer 的回复:
首先我觉得楼主还没搞清楚宽字符集与多字节字符集的区别 本来人家提供的函数就是 UNICODE 宽字符集的 你还多此一举的改来改去 UNICODE 为宽字符集,对应的字符类型为 wchar_t char 类型的才是多字节字符集 看到有什么不一样吗?宽字符集多了个 w 和 t 相对的 LPCTSTR 与 LPCSTR,哪个为 UNICODE?
我想您大概没搞清楚源文件和动态链接库的区别
Sandrer 2013-11-25
  • 打赏
  • 举报
回复
首先我觉得楼主还没搞清楚宽字符集与多字节字符集的区别 本来人家提供的函数就是 UNICODE 宽字符集的 你还多此一举的改来改去 UNICODE 为宽字符集,对应的字符类型为 wchar_t char 类型的才是多字节字符集 看到有什么不一样吗?宽字符集多了个 w 和 t 相对的 LPCTSTR 与 LPCSTR,哪个为 UNICODE?
许文君 2013-11-25
  • 打赏
  • 举报
回复
引用 7 楼 akirya 的回复:
[quote=引用 5 楼 xuddk727 的回复:] [quote=引用 4 楼 akirya 的回复:] LPCSTR name = GetName();生存周期啊 一般没有通过返回值返回字符串的
A2W, W2A, c_str() GetBuffer() .........[/quote] 但这些保存下来用随时都有效么?[/quote] 在栈上的肯定无效啊,要有效的比如sysallocstring,
  • 打赏
  • 举报
回复
引用 5 楼 xuddk727 的回复:
[quote=引用 4 楼 akirya 的回复:] LPCSTR name = GetName();生存周期啊 一般没有通过返回值返回字符串的
A2W, W2A, c_str() GetBuffer() .........[/quote] 但这些保存下来用随时都有效么?
许文君 2013-11-25
  • 打赏
  • 举报
回复
VC6的dll那你就用多字节字符集呗,还省得改那么多 getname可以开辟个内存传递出去,只要外面不去释放就好了。现在这玩意估计在栈上,你要么立即使用它,要么先拷贝过来存着,不然就会出你那样的
许文君 2013-11-25
  • 打赏
  • 举报
回复
引用 4 楼 akirya 的回复:
LPCSTR name = GetName();生存周期啊 一般没有通过返回值返回字符串的
A2W, W2A, c_str() GetBuffer() .........
  • 打赏
  • 举报
回复
LPCSTR name = GetName();生存周期啊 一般没有通过返回值返回字符串的
Walle_Oyq 2013-11-25
  • 打赏
  • 举报
回复
我用 std::string 成功的转换了,自己解决!
Walle_Oyq 2013-11-25
  • 打赏
  • 举报
回复
多字符集下的LPCTSTR不就是LPCSTR吗,从修改上来看也是对的,但是为什么直接传值可以,其他的就不行了呢
Walle_Oyq 2013-11-25
  • 打赏
  • 举报
回复
我想到现在都没有想到是为什么,所以大神,救救我吧!!!!!!!

16,473

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧