windows LoadLibrary 采用 LPCTSTR
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5208415/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
LoadLibrary taking a LPCTSTR
提问by Ben
I want to develop a plugin system using LoadLibrary.
My problem is: I want my function to take a const char*
and LoadLibrary
takes a LPCTSTR
.
I had the brightidea to do (LPCSTR)path
which kept giving me a module not found error.
Current code is below. If I uncomment the widepath = L..
line it works fine. I've read solutions using MFC but I'd like to not use MFC.
我想使用 LoadLibrary 开发一个插件系统。
我的问题是:我希望我的函数采用 aconst char*
并LoadLibrary
采用LPCTSTR
.
我有明亮的想法做(LPCSTR)path
这不停地给我找不到错误的模块。
当前代码如下。如果我取消注释该widepath = L..
行,它就可以正常工作。我已经阅读了使用 MFC 的解决方案,但我不想使用 MFC。
Current code:
当前代码:
bool PluginLoader::Load(char *path)
{
path = "Release\ExamplePlugin.dll";
LPCTSTR widepath = (LPCTSTR)path;
//widepath = L"Release\ExamplePlugin.dll";
HMODULE handle = LoadLibrary(widepath);
if (handle == 0)
{
printf("Path: %s\n",widepath );
printf("Error code: %d\n", GetLastError());
return false;
}
int (*load_callback)() = (int (*)()) GetProcAddress(handle, "_plugin_start@0");
if (load_callback == 0)
{
return false;
}
return load_callback() == LOAD_SUCCESS;
}
回答by Hans Passant
Use LoadLibraryA(), it takes a const char*.
使用 LoadLibraryA(),它需要一个 const char*。
Winapi functions that take strings exist in two versions, an A version that takes a Ansi strings and a W version that takes wide strings. There's a macro for the function name, like LoadLibrary, that expands to either the A or the W, depending if UNICODE is #defined. You are compiling your program with that #define in effect, so you get LoadLibraryW(). Simply cheat and use LoadLibraryA().
接受字符串的 Winapi 函数有两个版本,一个是接受 Ansi 字符串的 A 版本,另一个是接受宽字符串的 W 版本。函数名称有一个宏,如 LoadLibrary,它扩展为 A 或 W,具体取决于 UNICODE 是否为 #defined。您正在使用有效的#define 编译您的程序,因此您将获得 LoadLibraryW()。只需作弊并使用 LoadLibraryA()。
回答by Oscar Mederos
I suggest you using TCHAR
and LoadLibrary
instead of using manually char
or wchar_t
and LoadLibraryA
or LoadLibraryW
to make a generic application, both for UNICODEand ASCIIcharacters.
我建议您使用TCHAR
andLoadLibrary
而不是手动使用char
orwchar_t
和LoadLibraryA
orLoadLibraryW
来制作通用应用程序,包括UNICODE和ASCII字符。
So you could do:
所以你可以这样做:
TCHAR x[100] = TEXT("some text");
TCHAR x[100] = TEXT("some text");
I suggest you reading this article. LPCTSTR
is a const TCHAR*
.
我建议你阅读这篇文章。LPCTSTR
是一个const TCHAR*
。
Why use LoadLibrary
instead of LoadLibraryW
or LoadLibraryA
? To support both UNICODEand ASCIIwithout creating two different programs, one to work with char
and the other with wchar_t
.
为什么使用LoadLibrary
代替LoadLibraryW
或LoadLibraryA
?要同时支持UNICODE和ASCII而无需创建两个不同的程序,一个char
使用wchar_t
.
Also, take a look at what Microsoft says about it: Conventions for Function Prototypes
另外,看看微软是怎么说的:Conventions for Function Prototypes
回答by Mark Ransom
If you continue to use a char *
for the parameter, you'll run into cases where an unusual character is used in the filename and the LoadLibrary will fail. Change the function to use wchar_t instead, and while you're at it make the parameter const
since you're not modifying the string.
如果您继续使用 achar *
作为参数,您将遇到在文件名中使用异常字符并且 LoadLibrary 将失败的情况。将函数更改为使用 wchar_t ,并且当您使用它时,请创建参数,const
因为您没有修改字符串。
bool PluginLoader::Load(const wchar_t *path)
I think you'll find that LPCTSTR on 32-bit Windows is a macro that expands to const wchar_t *
when the program options are set to Unicode.
我想您会发现 32 位 Windows 上的 LPCTSTR 是一个宏,const wchar_t *
当程序选项设置为 Unicode 时,它会扩展到。
回答by Jerry Coffin
The approved method with LoadLibrary
is to notuse a char const *
, but instead use a TCHAR const *
, and use the _T
macro on all literals:
批准的方法 withLoadLibrary
是不使用 a char const *
,而是使用 a TCHAR const *
,并_T
在所有文字上使用宏:
bool PluginLoader::Load(TCHAR const *path) {
path = _T("Release\ExamplePlugin.dll");
HMODULE handle = LoadLibrary(path);
if (handle == 0)
{
_tprintf(_T("Path: %s\n"),widepath );
_tprintf(_T("Error code: %d\n"), GetLastError());
return false;
}
int (*load_callback)() = (int (*)()) GetProcAddress(handle, _T("_plugin_start@0"));
if (load_callback == 0)
{
return false;
}
return load_callback() == LOAD_SUCCESS;
}
This will automatically use LoadLibraryW
when _UNICODE
/UNICODE
are defined, and LoadLibraryA
when they're not. Likewise, _T
will give narrow or wide string literals on the same basis, so it all stays in sync.
这将LoadLibraryW
在_UNICODE
/UNICODE
被定义时自动使用,LoadLibraryA
当它们没有被定义时。同样,_T
将在相同的基础上给出窄或宽的字符串文字,因此它们都保持同步。
I generallyprefer to use the W
suffixed functions explicitly, and use the L
prefix on string literals. Windows works almost exclusively with wide strings internally anyway, so the version A
-suffixed versions that take narrow string literals are mostly small stubs that convert their arguments to wide strings, then call the wide string version. Using the wide string version directly saves both time and memory.
我通常更喜欢W
显式使用后缀函数,并L
在字符串文字上使用前缀。无论如何,Windows 在内部几乎只使用宽字符串,因此A
采用窄字符串文字的版本后缀版本大多是将其参数转换为宽字符串的小存根,然后调用宽字符串版本。直接使用宽字符串版本既节省时间又节省内存。
Narrow string support in Windows was originally there primarily for compatibility with the long-since defunct Windows 95/98/SE/Me line that lacked wide string support. Those have been gone for quite a while, so about the only reason to use narrow literals now is because that's what you're being supplied from some outside source.
Windows 中的窄字符串支持最初主要是为了与缺乏宽字符串支持的早已不复存在的 Windows 95/98/SE/Me 系列兼容。那些已经消失了很长一段时间,所以现在使用窄文字的唯一原因是因为这是从某些外部来源提供的。