【问题标题】:using unicode dlls in MBCS projects or vice versa在 MBCS 项目中使用 unicode dll,反之亦然
【发布时间】:2015-07-28 10:49:00
【问题描述】:

我有一个 vc++ dll,它使用设置为“使用 Unicode 字符集”的字符集进行编译。 现在我想在我的 vc++ exe 中使用这个 dll,它的字符集是“使用多字节字符集”。我知道理论上没有什么能阻止我这样做,因为在编译 vc++ dll 之后,所有函数签名都是 wchar_t 或 LPCWSTRs .. 在我的 vc++ exe 中,我只是创建该格式的字符串并调用导出的函数。但是,我面临的问题是,unicode dll 中的标头采用 TCHAR 参数,例如:

class MYLIBRARY_EXPORT PrintableInt
{
public:
    PrintableInt(int value);
    ...
    void PrintString(TCHAR* somestr);

private:
   int m_val;
};

现在我想在我的 exe 中使用这个 PrintString()。所以,我包含了标题并像下面这样使用它:

#include "unicodeDllHeaders.h"
PrintableInt p(2);
wchar_t* someStr = L"Some str";
p.PrintString(someStr);

这正如预期的那样给了我一个编译器错误:

error C2664: 'PrintableInt::PrintString' : cannot convert parameter 1 from 'wchar_t *' to 'TCHAR *'

由于 exe 是使用 MBCS 构建的,因此 TCHAR 被定义为 char 。所以,我认为可以解决这个问题的是:

#define _UNICODE
#include "unicodeDllHeaders.h"
#undef _UNICODE

但在定义 _UNICODE 之后,我仍然得到编译错误。所以,我的下一个猜测是 TCHAR.h 可能已经包含在 #include "unicodeDllHeaders.h" 之前,当我搜索 TCHAR.h 的包含时,它在项目的其他位置。因此,我将包含内容移到了 _UNICODE 的定义之后,这解决了此处的编译错误,但在其他预期将 TCHAR 设为 char 的地方却失败了。所以,我的问题是:

我可以让 TCHAR 在同一个项目中解析为 char 和 wchar_t 吗?我试过#define TCHAR char、#undef TCHAR、#define TCHAR wchar_t,但它在xutils等c头文件中失败了

【问题讨论】:

    标签: c++ c visual-c++ dll unicode


    【解决方案1】:

    无论使用宏对头文件做什么,您都不能追溯更改 DLL 的二进制接口。典型的解决方案是首先转储整个遗留 MBCS 内容。这在 10 年前就不再有趣了,现在所有支持 win32 API 的目标都支持具有完整 Unicode 支持的宽字符接口。

    如果您想要那种 90 年代的复古感觉,您还可以编译您的 DLL 两次,一次使用 CHAR,一次使用 WCHAR。后者通常会得到一个“u”后缀(对于 Unicode)。然后在您的标头中检查字符集并使用 #pragma comment lib.. 委托给相应的 DLL。

    【讨论】:

    • 我明白,但我无法控制 dll。那是我无法更改的旧版 dll。现在,我最终得到了一个包含两个头文件的 exe,其中一个头文件中的 TCHAR 应映射到 char,而另一个 TCHAR 应映射到 wchar_t。有什么办法可以做到吗?
    • 好吧,我理解你的意思,你有一个单独的 DLL,它的头文件使用TCHAR。那么问题是头文件实际上并没有描述DLL的二进制接口,因为在DLL中它们实际上使用WCHARCHAR。解决方案很简单:修复头文件。将所有TCHAR(和PTSTR等)替换为与DLL接口匹配的相应声明。
    • Ok .. 所以不要修复我在我的 exe 中包含 dll 标头的方式,您建议我修改我必须具有实际定义为 dll 中的具体类型的 dll 标头,例如char/wchar_t 或 LPSTR/LPWSTR ... 这必须有效,并且只是为了获得整体情况,是否有可能在我的 exe 头文件/源代码中修复这个问题,我在其中包含这些 dll 头文件以将 TCHAR 定义为 char 和 wchar_t通过一些#define s,例如 _UNICODE 或 _TCHAR_DEFINED ?.
    • 为了将标头包装在预处理器宏中作为修复,您必须首先重新定义所有 TCHAR 类型,然后包含标头,然后恢复原始定义。此外,必须首先包含 DLL 标头中包含的任何标头(如 tchar.h),以便包含防护呈现防止它们的干扰。您必须在每个包含 DLL 标头的地方都这样做。此外,为了维护,添加相应的注释来解释问题。不过我宁愿修补头文件,这样更可靠。
    猜你喜欢
    • 2010-09-27
    • 2013-10-01
    • 2012-11-19
    • 1970-01-01
    • 1970-01-01
    • 2010-10-16
    • 2013-10-16
    • 2012-01-24
    • 2011-08-18
    相关资源
    最近更新 更多