我在应用程序中使用C++ DLL。
type
Tcl_bla = function(filename: PChar): Integer; cdecl;
var
cl_bla: Tcl_bla;
function CallLibraryProc(Proc: String): Pointer;
begin
Result := GetProcAddress(Handle, PChar(Proc));
if not Assigned(Result) then
Loaded := False;
if not Loaded then
MessageBox(0, PChar('Error => ' + Proc), 'Alert', MB_OK or MB_TOPMOST);
end;
...
Handle := SafeLoadLibrary(
PChar(CurrentPath + Dll),
SEM_FAILCRITICALERRORS or SEM_NOGPFAULTERRORBOX or SEM_NOOPENFILEERRORBOX
);
if (Handle < HINSTANCE_ERROR) then
raise Exception.Create(
Dll + ' library can not be loaded or not found.' + SysErrorMessage(GetLastError)
);
if Handle <> 0 then
begin
// blabla
cl_bla := CallLibraryProc('cl_bla');
end;
...
FreeLibrary(Handle);
上面的代码与D6配合使用。我正在尝试移植我的代码,以便它可以在具有Unicode支持的Delphi中运行,但是我遇到了麻烦。
我已经阅读了Embarcadero关于GetProcAddress的文档
procedure CallLibraryProc(const LibraryName, ProcName: string);
var
Handle: THandle;
RegisterProc: function: HResult stdcall;
begin
Handle := LoadOleControlLibrary(LibraryName, True);
@RegisterProc := GetProcAddress(Handle, PAnsiChar(AnsiString(ProcName)));
end;
我无法尝试此操作,因为我不知道如何声明LoadOleControlLibrary!
我的CallLibraryProc可以加载DLL,但是cl_bla无法正常工作。
我认为由于GetProcAddress的参数或我的代码存在问题。也许我移植的 header 是错误的。
最佳答案
我不妨将此作为答案发布,因为它看起来像答案!
您所说的D6代码在D2010中无需修改即可正常工作,并且具有相同的含义。 Windows.pas中有两个GetProcAddress
重载。其中之一从Unicode转换为ANSI。因此,您可以像往常一样调用GetProcAddress(Handle, PChar(Proc))
。
魔术看起来像这样:
function GetProcAddress(hModule: HMODULE; lpProcName: LPCWSTR): FARPROC;
begin
if ULONG_PTR(lpProcName) shr 16 = 0 then // IS_INTRESOURCE
Result := GetProcAddress(hModule, LPCSTR(lpProcName))
else
Result := GetProcAddress(hModule, LPCSTR(AnsiString(lpProcName)));
end;