Entwickler-Ecke

Sonstiges (.NET) - Unmanaged DLL dynamisch laden & per Index zugreifen


doublecross - Fr 24.05.19 14:33
Titel: Unmanaged DLL dynamisch laden & per Index zugreifen
Hallo,

ich bin gerade damit beschäftigt eine Funktionalität aus einem alten Delphi Programm in C# zu übertragen.
Dabei bin ich über eine knifflige stelle gestolpert.

Es wird eine ZIP Datei geladen und entpackt. In dieser befindet sich unter anderen eine DLL, welche für die weiteren Schritte verwendet werden muss. Von dieser Dll gibt es verschiedene Versionen. In den älteren Varianten der Dll haben die Funktinen einen Namen, in neueren können sie nur per Index aufgerufen werden.

In der Delphi Variante habe ich die folgenden beiden Funktionen, welche abhängig von der DLL Version verwendet werden:


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
Function GetDLLFuncByIndex(aFuncIndex: tCard16): FARPROC;
Var
  Findex : tCard32;
Begin
  {$WARNINGS off}
    Result := nil;
  {$WARNINGS on}
  If (fDLL <> 0Then
    Begin
      Findex := $00000000 Or aFuncIndex;
      Result := GetProcAddress(fDll, tPtr(Findex));
      If Not Assigned(Result) Then
        raise Exception {...}
    End
  Else
    raise Exception {...}
End;

Function GetDLLFuncByName(aFuncName: tStrStd): FARPROC;
Begin
  {$WARNINGS off}
    Result := nil;
  {$WARNINGS on}
  If (fDLL <> 0Then
    Begin
      Result := GetProcAddress(fDll, pAnsiChar(aFuncName));
      If Not Assigned(Result) Then
        raise Exception  {...}
    End
  Else
    raise Exception  {...}
End;


Ich tue mich jetzt schwer insbesondere die erste Version.

Ich finde im Netz mehrere Beispiele zum Dynamischen laden, von unmanaged DLLs, welche alle auf der Verwendung der entsprechenden kernel 32 Funktionen basieren:


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
        [DllImport("kernel32.dll")]
        public static extern IntPtr LoadLibrary (string dllToLoad);

        [DllImport("kernel32.dll")]
        public static extern IntPtr GetProcAddress (IntPtr hModule, string procedureName);


        [DllImport("kernel32.dll")]
        public static extern bool FreeLibrary (IntPtr hModule);


Nur wie bekomme ich da den Aufruf einer Funktion per Index hin?


Th69 - Fr 24.05.19 15:54

Lege einfach eine Überladung davon an:

C#-Quelltext
1:
2:
[DllImport("kernel32.dll")]
public static extern IntPtr GetProcAddress(IntPtr hModule, int procedureIndex);

s.a. GetProcAddress [https://docs.microsoft.com/en-us/windows/desktop/api/libloaderapi/nf-libloaderapi-getprocaddress]:
Zitat:
lpProcName

The function or variable name, or the function's ordinal value. If this parameter is an ordinal value, it must be in the low-order word; the high-order word must be zero.


Delete - Fr 24.05.19 16:29

- Nachträglich durch die Entwickler-Ecke gelöscht -


Th69 - Fr 24.05.19 17:51

Nein, es muß schon ein int (d.h. 4 Byte) übergeben werden, nur dürfen dort nur Werte bis max. 0xFFFF(65535) drin stehen.
Umgekehrt wird von dieser Funktion für Strings (Namen) angenommen, daß diese immer eine Adresse größer als diesen Wert besitzen.


doublecross - Fr 24.05.19 18:04

Danke user profile iconTh69,

das war mal wieder zu einfach. Ich werde zwar erst Montag dazu kommen das ausgiebig zu testen, aber ich gehe schwer davon aus, dass die Frage damit beantwortet ist.