开发者

Can a Windows app compiled using the Unicode character set use a DLL compiled as Multi-Byte?

开发者 https://www.devze.com 2023-01-08 19:59 出处:网络
I suspect the answer is \"no\", since when I go to include the header, the \"T\" macros will be defined to use (wchar_t *), but the DLL is expecting (char *). However, I was wondering whether Windows

I suspect the answer is "no", since when I go to include the header, the "T" macros will be defined to use (wchar_t *), but the DLL is expecting (char *). However, I was wondering whether Windows did any on-the-fly transcoding between modules that would make this magically work (ass开发者_Python百科uming simple ASCII characters).


No, Windows won't do any magical on-the-fly conversion. You would have to do it yourself.

Here is how I would probably do it:

Create a wrapper DLL, compiled as multi-byte (to ensure that the headers of the wrapped DLL are interpreted correctly). However, in the code for the wrapper itself, as well as its header, I would not use any of the ANSI/UNICODE macros like _T, instead, I would explicitly use char and 'wchar_t' as needed.

For each function of the wrapped DLL that you need, if it has any character input or output (directly, or in structs), write a wrapper function, that converts the input strings (of type 'wchar_t *') to 'char *' strings via 'WideCharToMultiByte' before calling the wrapped function. Likewise, convert output parameters back to Unicode using 'MultiByteToWideChar'.


You will be able to load it, but in the case of special characters the character codes will not be well interpreted. You could try to make a "wrapper DLL" that loads the Multi-Byte Dll and maps all function calls.It will pass on all the calls from one side to the other but it will "transcode" the strings in the function calls and in the returned variables :)


You can do this as long as your dll doesn't have any other conflicting dll dependencies. You will need to make sure you define the functions in your code of the dll using "..." instead of _T("...") and CStringA instead of CString.


What windows does to enable this is, all windows API functions are defined twice: SetWindowText for example exists as SetWindowTextA and SetWindowTextW - SetWindowText is actually a macro that changes based on whether UNICODE is defined or not.

So, if you are dealing with a DLL that was compiled with that usage in mind - then the Dll will export an ANSI AND a Unicode API - and header files will switch between the two.

If the DLL was compiled - like your application - with TCHAR's internally, then there are really two possible builds of the DLL - an ansi build and a unicode build - with potentially no real way to tell them apart - at which point calling the dll with the wrong kind of string will just make it fail.


The symbols exported from the one will even look different from those imported by the other - at least when using C++. So the client dll won't even be able to load, since it cannot find the expected symbols in the server dll.

-- EDIT --

In case you're using C-type export symbols, which don't contain type information, you will be able to load the dll. However, when giving it a wchar_t string L"abc", the two-byte per character string will be encoded as { 65 00 66 00 67 00 00 00 }, so the target dll will interpret the zero-terminated string as "a".

0

精彩评论

暂无评论...
验证码 换一张
取 消