delphi dll中的导出是否区分大小写?

3htmauhk  于 2023-05-06  发布在  其他
关注(0)|答案(2)|浏览(193)

我正在使用win7和 Delphi 2010。这是我的代码。

library CFGFunc;

uses
sysUtils
Un_ExFuncDll in "base\Un_ExFuncDll.pas"
...

exports
LoadExFuncsInDLL,
...

Un_ExFuncDll.pas在这里

unit Un_ExFuncDll;
interface    
uses
  Classes;
  procedure LoadexfuncsIndll(); stdcall;
  ...

编译后,dll不工作。但是,我在Un_ExFuncDll.pas中将LoadexfuncsIndll()替换为LoadExFuncsInDLL()(与导出中的内容完全匹配)。然后,它工作。
Delphi 不区分大小写。但似乎dll中的导出是区分大小写的。他们是怎么回事

vd8tlhqk

vd8tlhqk1#

导入/导出DLL函数区分大小写的,而且一直如此。该行为与OS DLL加载程序绑定,后者区分大小写。这是 Delphi 语言中区分大小写的唯一领域之一。这是有记录的行为,至少部分是:
Writing Dynamically Loaded Libraries

name说明符由指令name和字符串常量组成。如果条目没有name说明符,则例程将以其原始声明的名称导出,具有相同的拼写和大小写。如果要以不同的名称导出例程,请使用name子句。

程序和函数( Delphi )
在导入声明中,确保与例程名称的拼写和大小写完全匹配。以后,当您调用导入的例程时,该名称不区分大小写。

mxg2im7a

mxg2im7a2#

如果你有数百个导出的函数和未知数量的dll,并且你无意中使用了一些导出例程的名称,这是一个真实的的PIA。
有个办法可以解决

procedure GetExportedFunctions(const ModulePath: string; names: TStringList);

  function RvaToVa(Module: HMODULE; Rva: Cardinal): Pointer;
  begin
    Result := Pointer(Rva + Module);
  end;

var
  Module: HMODULE;
  DosHeader: PImageDosHeader;
  NtHeaders: PImageNtHeaders;
  EntryData: PImageExportDirectory;
  POrd: PWord;
  p: PDWORD;
  i: integer;

begin
  names. Clear;

  Module := LoadLibraryEx(PChar(ModulePath), 0, LOAD_LIBRARY_AS_DATAFILE);
  if Module = 0 then
       RaiseLastOSError;

  try
    DosHeader := PImageDosHeader(Module);
    NtHeaders := PImageNtHeaders(NativeUInt(Module) + DosHeader._lfanew);
    EntryData := RvaToVa(Module, NtHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);

    if not Assigned(EntryData) then
         Exit;

    with EntryData^ do begin
      POrd := RvaToVa(Module, AddressOfNameOrdinals);
      p := RvaToVa(Module, AddressOfNames);
    end;

    { Function names }
    for i := 0 to EntryData^.NumberOfNames - 1 do begin
      names. Add(string(PAnsiChar(RvaToVa(Module, p^))));
      Inc(p);
      Inc(POrd);
    end;
  finally
    FreeLibrary(Module);
  end;
end; { GetExportedFunctions }

function GPA_CaseInsensitive(Module: HMODULE; const ProcName: string): Pointer;
var
  EnumNames: TStringList;
  i: integer;
  FuncName: string;

begin
  Result := nil;

  EnumNames := TStringList.Create;
  try
    GetExportedFunctions(GetModuleName(Module), EnumNames);
    for i := 0 to EnumNames.count - 1 do begin
      FuncName := EnumNames[i];
      if SameText(FuncName, ProcName) then begin
        Result := GetProcAddress(Module, PChar(FuncName));
        Break;
      end;
    end;

    if not Assigned(Result) then begin
      MessageBox(0, PChar(Format('Function %s not found in module', [ProcName])),
         'DLL Error', MB_SYSTEMMODAL or MB_SETFOREGROUND or MB_TOPMOST or MB_ICONHAND);
    end;
  finally
    EnumNames.Free;
  end;
end; { GPA_CaseInsensitive }

相关问题