什么';Delphi中这些Windows API签名之间的区别是什么?
查看Delphi中的Windows.pas,我看到有几个签名,如加载特定模块的什么';Delphi中这些Windows API签名之间的区别是什么?,windows,delphi,winapi,Windows,Delphi,Winapi,查看Delphi中的Windows.pas,我看到有几个签名,如加载特定模块的LoadLibrary(A)或(W)。它们之间的区别是什么?我可以相信总是为所有类型的Windows平台调用LoadLibrary吗?Windows API提供ANSI字符串(A)或Unicode字符串(W)。在内部,Windows API提供了这两种功能。但是,根据Delphi的版本,Delphi默认为一个或另一个。许多其他Windows语言也这样做。该语言使用ANSI或Unicode字符串作为默认值 在2009年之
LoadLibrary(A)或(W)
。它们之间的区别是什么?我可以相信总是为所有类型的Windows平台调用LoadLibrary吗?Windows API提供ANSI字符串(A
)或Unicode字符串(W
)。在内部,Windows API提供了这两种功能。但是,根据Delphi的版本,Delphi默认为一个或另一个。许多其他Windows语言也这样做。该语言使用ANSI或Unicode字符串作为默认值
在2009年之前的Delphi版本中,使用了ANSI API调用,后缀为A
。那时Delphi主要使用ANSI字符串。自Delphi 2009及更高版本起,Unicode已被强制执行。这也使得默认API调用Unicode,后缀为W
。在Delphi中,Unicode一直都是受支持的,但从2009年起,它被强制作为默认值,优于ANSI。在那些旧版本中,诸如LoadLibrary
之类的函数映射到ANSI版本LoadLibraryA
您所指的特定API调用LoadLibrary
可以作为LoadLibraryA
或LoadLibraryW
提供Windows.h
还提供了一个通用的LoadLibrary
函数,该函数在内部使用首选的Unicode版本。与微软的许多产品一样,A
和W
的差异为开发者提供了向后兼容的选项。如果语言主要是ANSI字符串,则可以显式使用Unicode。或者,如果语言主要是Unicode,则可以显式使用ANSI
长话短说,Windows本身曾一度默认从ANSI字符串切换到Unicode字符串。但是仍然提供了向后兼容性。后来的Delphi版本已经更改为使用任何首选默认值-在本例中,它们是Unicode
总结如下:
- LoadLibraryA-通过ANSI字符串加载库
- LoadLibraryW-通过Unicode字符串加载库
- LoadLibrary-使用首选默认值(Unicode字符串)加载库
- 在引入Unicode之前,Windows的古代版本只使用ANSI字符串
- Windows通过默认为ANSI版本提供了向后兼容性,但最终将默认值切换为Unicode(不确定是哪个版本)
LoadLibraryA()
(Ansi)和LoadLibraryW()
(Unicode)定义为实际函数(从kernel32.dll导出)LoadLibrary()
根本不是一个函数,它是一个预处理器宏(在winbase.h
中定义),根据项目是否配置为针对Ansi或Unicode环境编译,映射到LoadLibraryA()
或LoadLibraryW()
:
#ifdef UNICODE
#define LoadLibrary LoadLibraryW
#else
#define LoadLibrary LoadLibraryA
#endif
当C/C++应用程序使用基于TCHAR
的字符串调用通用LoadLibrary()
函数时,只需更改项目设置而不是更改源代码,即可为任一环境编译和链接该函数,例如:
HMODULE hLib = LoadLibrary(TEXT("filename"));
// calls either LoadLibraryA("filename") or LoadLibraryW(L"filename")
// depending on whether UNICODE is defined while compiling...
另一方面,Delphi不支持.h
文件,因此无法利用Microsoft现有的所有函数声明。所有库函数和数据类型都必须在Pascal中重新声明(因此存在Windows
单元和Win32 API的其他相关单元)
在LoadLibrary()
的情况下,Delphi的所有版本都将LoadLibraryA()
和LoadLibraryW()
声明为从kernel32.dll
导入的实函数,分别使用PAnsiChar
和PWideChar
参数:
function LoadLibraryA(const lpFileName: PAnsiChar): HMODULE; stdcall; external kernel32 name 'LoadLibraryA';
function LoadLibraryW(const lpFileName: PWideChar): HMODULE; stdcall; external kernel32 name 'LoadLibraryW';
Delphi不支持预处理器宏,因此它将LoadLibrary()
声明为一个函数,用于导入与Delphi的泛型PChar
类型匹配的DLL函数。因此,在Delphi 2007和更早版本中,PChar
是PAnsiChar
,LoadLibrary()
被声明为导入LoadLibraryA()
,在Delphi 2009和更高版本中,PChar
是PWideChar
,LoadLibrary()
被声明为导入LoadLibraryW()
:
// Delphi 2007 and earlier...
function LoadLibrary(const lpFileName: PChar): HMODULE; stdcall; external kernel32 name 'LoadLibraryA';
当Delphi应用程序使用PChar
调用通用LoadLibrary()
时,它可以在Delphi的多个版本中编译,而无需更改源代码:
hLib := LoadLibrary(PChar(filename));
// calls either LoadLibraryA(PAnsiChar(filename) or LoadLibraryW(PWideChar(filename))
// depending on whether Delphi natively uses Ansi or Unicode strings...
这些因素适用于任何基于TCHAR的API,而不仅仅适用于加载库()。当给定的Win32 API支持
a
和W
版本时,MSDN将根据其通用TCHAR
版本对其进行记录。请记住,Win32 API早于Unicode,而TCHAR
是Microsoft的解决方案,它在Windows NT中首次引入Ansi API时,将开发人员从Ansi API迁移到Unicode API,同时仍然允许开发人员支持早期的Windows版本。为了向后兼容遗留应用程序,这些现有的Ansi API在现代Windows版本中仍然受支持,尽管有人反对使用Unicode API。新引入的API倾向于只采用Unicode编码。简而言之。。。Delphi中这两个LoadLibrary和LoadLibraryW签名之间存在差异?我可以理解下载投票,但我不明白为什么不清楚询问的是什么。更新标题以反映所问问题。@Jerrydoge编辑后的问题会更好。我投票赞成重新提出这个问题。
hLib := LoadLibrary(PChar(filename));
// calls either LoadLibraryA(PAnsiChar(filename) or LoadLibraryW(PWideChar(filename))
// depending on whether Delphi natively uses Ansi or Unicode strings...