GetModuleFileNameA和GetModuleFileNameW以及GetModuleFileName

GetModuleFileNameA和GetModuleFileNameW以及GetModuleFileName确切的说 GetModuleFil 的定义是一个宏 在 UNICODE 版本下 GetModuleFil 等同于 GetModuleFil 在 ANSI 版本下等同于 GetModuleFil nbsp nbsp nbsp nbsp GetModuleFil 和 GetModuleFil 的区别在于它们的字符串参数的 字符宽度 这两个函数的原型如下 D

   确切的说,GetModuleFileName的定义是一个宏,在UNICODE版本下,GetModuleFileName等同于GetModuleFileNameW,在ANSI版本下等同于GetModuleFileNameA

       GetModuleFileNameA和GetModuleFileNameW的区别在于它们的字符串参数的“字符宽度”,这两个函数的原型如下:

 DWORD WINAPI GetModuleFileNameA( HMODULE hModule, 
 LPSTR lpFilename, DWORD nSize );//ANSI版本,第二个参数是LPSTR,也就是char*。
 这意味着你需要向其传递的参数是char类型的字符串
 DWORD WINAPI GetModuleFileNameW( HMODULE hModule, 
 LPWSTR lpFilename, DWORD nSize );//UNICODE版本,第二个参数是LPWSTR,也就是wchar_t*。
 这意味着你需要向其传递的参数是wchar_t类型的字符串。

       如果你的代码预定义了宏“UNICODE”,那么在编译时,“GetModuleFileName”就会被替换成”GetModuleFileNameW”, 否则就是“GetModuleFileNameA”。同理,_tcsrchr也是一个宏,当预定义了“_UNICODE”宏是,它会在编译时替换成为

 wchar_t *wcsrchr( const wchar_t *str, wchar_t c ); // C only

       因为凡是涉及字符串的函数,几乎都有对应的ANSI和UNICODE版本,比如wcsrchr、strrchr、strcmp、wcscmp等等。在你的代码中对各个接口、函数的ANSI版本和UNICODE版本的使用应该始终保持一致,以避免出现错误。

       而你的代码,首先明确使用了ANSI版本的接口GetModuleFileNameA,而其后又将ANSI字符串提交给UNICODE版本的wcsrchr使用,所以会出现错误。

        另:关于char和wchar_t的区别想必你应该了解,wchar_t字符串中每一个字符都由两个字节组成,对于ascii表中的字符,都会在高位字节补0以补齐两个字节。字符a其ascii码为0x61,用char类型表示时其值为0x61,但是用wchar_t表示时,由于wchar_t为双字符,因此其值应是0x0061——在INTEL x86和x64架构的系统中,字节序列表示就成了“0x61 0x00”。

        比如有字符串”abcdefg”,当你用char类型表示这一串字符串时,C代码会这样写:

 char aString[] = {"abcdefg"};

      它在内存中的存在形式将是这样的:

  61 62 63 64 65 66 67 00                         ; abcdefg.

  如果用wchar_t去表示,C代码如下:

 wchar_t wString[] = {L"abcdefg"};

      在内存中的存在形式就会变为这样:

  61 00 62 00 63 00 64 00 65 00 66 00 67 00 00 00 ; a.b.c.d.e.f.g…
  由于每个字符都要双字符表示,因此在此示例中wchar_t表示的字符串会多了一半的0。当你把wchar_t表示的字符串字节序列强行当作char*类型来处理时,就会出现意料之外的问题。
       因此你的代码应该这样写:

 TCHAR tszCfgFile[MAX_PATH]={0};//TCHAR也是宏定义,当预定义了UNICODE时,等同于wchar_t,否则
 等于char。与GetModuleFileName的宏定义保持一致。 GetModuleFileName( gDllModule, tszCfgFile, MAX_PATH); _tcsrchr( tszCfgFile, _T('\\') )[1] = 0;//这样写是危险的,如果tszCfgFile并不包含\\,此行将导致崩溃。








版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/218020.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 上午8:14
下一篇 2026年3月18日 上午8:14


相关推荐

  • 什么是5g微基站(三大运营商基站数量)

    大家都知道,要想使用5G网络,必须要有5G基站做支撑,那么5G基站长啥样,又是如何建成的呢?▲中国移动的5G天线设备▲北斗+GPS的双星授时设备5G天线设备、北斗+GPS的双星授时设备两…

    2022年4月11日
    113
  • pycharm如何缩进多行代码_pycharm整段代码缩进

    pycharm如何缩进多行代码_pycharm整段代码缩进pycharm多行代码缩进、左移在使用pycharm时,经常会需要多行代码同时缩进、左移,pycharm提供了快捷方式1、pycharm使多行代码同时缩进鼠标选中多行代码后,按下Tab键,一次缩进四个字符2、pycharm使多行代码同时左移鼠标选中多行代码后,同时按住shift+Tab键,一次左移四个字符…

    2022年8月25日
    6
  • invoke方法的使用

    invoke方法的使用

    2022年6月12日
    35
  • scrapy框架简介

    scrapy框架简介一 scrapy 简介 Scrapy 是用纯 Python 实现一个为了爬取网站数据 提取结构性数据而编写的应用框架 用途非常广泛 Scrapy 使用了 Twisted 其主要对手是 Tornado 异步网络框架来处理网络通讯 可以加快我们的下载速度 不用自己去实现异步框架 并且包含了各种中间件接口 可以灵活的完成各种需求 1 下载 scrapypipins 二 scrapy 开发流程 1 新建项目 scrapystartp 项目名 2 新建 spider 爬虫模板先

    2026年3月26日
    2
  • django filter查询_搜索全局排序方法

    django filter查询_搜索全局排序方法前言当我们需要对后台的数据进行过滤的时候,drf有两种,搜索过滤和排序过滤。搜索过滤:比如我们想返回sex=1的,那么我们就可以从所有数据中进行筛选排序过滤:比如我们想对价格进行升序排列,就可以

    2022年7月31日
    9
  • ROS创建Web代理(Web proxy)「建议收藏」

    ROS创建Web代理(Web proxy)「建议收藏」使用Web代理可以提高网页的访问速度,因为访问的数据会存储在内存或是硬盘中,就会直接从代理服务器中读取。同时,为了提高网络访问的安全性,可以给Web代理服务器设置相应的权限,使它的安全性得到提高。下面就介绍如何在RouterOS中创建Web代理的方法。一、启用Web-Proxy启用路径:IP/Web-Proxy,然后点击WebProx…

    2022年6月21日
    97

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号