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

问题描述 投票:0回答:2

我在 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 不工作。但是我用

LoadexfuncsIndll()
替换了
LoadExFuncsInDLL()
(与出口中的完全匹配)在
Un_ExFuncDll.pas
。然后它起作用了。

Delphi 不区分大小写。但是好像dll里面的exports是case sensitive的。 那么,他们有什么关系呢?

windows delphi dll case-sensitive
2个回答
11
投票

导入/导出 DLL 函数 IS 区分大小写,并且一直如此。该行为与区分大小写的 OS DLL 加载程序相关联。这是 Delphi 语言中仅有的区分大小写的区域之一。这是记录在案的行为,至少部分是:

编写动态加载的库

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

过程和函数(Delphi)

在您的导入声明中,确保与例程名称的拼写和大小写完全匹配。稍后,当您调用导入的例程时,名称不区分大小写。


0
投票

如果您有数百个导出函数和未知数量的 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 }
© www.soinside.com 2019 - 2024. All rights reserved.