美文网首页
windows开发-TCHAR之痛

windows开发-TCHAR之痛

作者: 肥树仙僧 | 来源:发表于2018-08-18 15:32 被阅读0次

    说到TCHAR,大家应该是不陌生。

    TCHAR简介

    为什么会有TCHAR,因为C++支持两种字符集,如下:

    • ANSI字符集:Multi-Byte Character
    • Unicode字符集:Unicode Character

    VS2008中字符集设置:
    右键工程-“Properties”-“Configuration Properties”-“General”-“Character Set”。

    微软baba为了统一这两套编码,所以有了TCHAR这个怪咖,通过条件编译(_UNICODE宏和UNICODE宏)控制实际使用的字符集。

    TCHAR详细信息

    • Use Unicode Character Set,其定义如下:
      typedef WCHAR TCHAR, *PTCHAR
      其中WCHAR的定义为:typedef wchar_t WCHAR
    • Use Multi-Byte Character Set,其定义如下:
      typedef char TCHAR, *PTCHAR

    已知char类型长度为1个字节,而wchar_t类型长度为2个字节;

    那么可知,TCHAR类型在Multi-Byte字符集下占1个字节,在Unicode字符集下占2个字节。

    同一个TCAHR类型的数组变量在不同字符集下,长度是不同的。
    TCHAR ptszArray[10];

    • 在Unicode字符集下,长度为20个字节
    • 在Multi-Byte字符集下,长度为10个字节

    问题

    扯了这么多闲话,说说正事
    这次问题牵涉到一个dll和exe,大致情况如下:

    dll:Unicode字符集
    exe:Multi-Byte字符集

    exe加载dll后通过一个获取函数列表接口获取所有函数指针,该接口的参数为一个函数指针结构体,大致如下:

    typedef struct BLKFUNLISTTAG
    {
      TCHAR   m_ptszDevName[10];
      Fun1    m_pFun1;
      Fun2    m_pFun2;
    }BlkFunList, *pBlkFunList;
    

    dll和exe中都是使用TCHAR数组,导致在dll中明明结构体中的2个函数指针已经被赋值;但是运行到exe后,却发现2个函数指针的值全为零。WTF!!!
    后来经过分析,是TCHAR捣的鬼。

    在dll中TCHAR实际上是wchar_t,则m_ptszDevName[10]的长度为20个字节,而到了exe后,TCHAR实际上是char,其长度为10个字节。
    假如DevName为"HID",由于dll为Unicode字符集,则其内存信息如下:
    \x00\x68\x00\x69\x00\x64\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
    exe里拿到上面这段内存地址,会按照char类型去解析。则只会取前面10个字节的数据:
    \x00\x68\x00\x69\x00\x64\x00\x00\x00\x00
    剩余的10个字节就会覆盖结构体后面的两个函数指针成员,最终导致2个函数指针的值为0。
    哎,想想都觉得可怕。

    解决方案

    为了不影响dll和exe中现有代码,所以只是将exe中结构体定义中的m_ptszDevName的类型由TCHAR改为WCHAR

    相关文章

      网友评论

          本文标题:windows开发-TCHAR之痛

          本文链接:https://www.haomeiwen.com/subject/zjdfiftx.html