2009-03-04 4 views
1

Können Sie mir sagen, wie verwende ich die folgenden Funktionen in meinem C-Programm.Wie man eine Funktion von einer DLL importiert, die in Delphi gemacht wird?

Delphi DLL - Exportierte Funktionen:

function GetCPUID (CpuCore: byte): ShortString; stdcall; 
function GetPartitionID(Partition : PChar): ShortString; stdcall; 

Ich habe nicht den Quellcode für die DLL so dass ich zu dieser DLL mein C-Programm anpassen muss und nicht umgekehrt.

ich folgende und bekommen Fehler

typedef char* (_stdcall *GETCPUID)(BYTE); 
typedef char* (_stdcall *GETPID)(PCHAR); 
GETCPUID pGetSerial; 
GETPID pGetPID 

HMODULE hWtsLib = LoadLibrary("HardwareIDExtractor.dll"); 
if (hWtsLib){ 
pGetSerial = (GETCPUID)GetProcAddress(hWtsLib, "GetCPUID"); 
char *str = (char*) malloc(1024); 
str = pGetSerial((BYTE)"1"); 

pGetPID= (GETPID)GetProcAddress(hWtsLib, "GetPartitionID"); 
char *str1 = (char*) malloc(1024); 
str1 = pGetPID("C:"); 
} 

Dank

+0

Welchen Fehler bekommen Sie genau? Ohne diese Information ist es schwer zu helfen. – rusvdw

+0

Das Programm wird kompiliert und ausgeführt, aber es stürzt beim Aufruf der DLL-Funktion ab. – Ampere

Antwort

7

Da Sie nicht die Quelle für die DLL haben, müssen Sie ein wenig kreativ auf der C-Seite der Dinge bekommen. Obwohl der ShortString als Funktionsergebnis aufgeführt ist, liegt es in der Verantwortung des Aufrufers Aufrufer, einen Speicherort anzugeben, in dem das Ergebnis platziert werden kann. Da dies eine stdcall-Funktion ist, werden Parameter von rechts nach links übergeben, was bedeutet, dass die Adresse des ShortString-Ergebnisses zuletzt übergeben wird. Um dies zu erreichen, muss der erste Parameter aufgelistet werden. Ich mache die erste API, GetCPUID. In C, könnte es etwa so aussehen:

typedef struct ShortString { 
    char len; 
    char data[255]; 
}; 
typedef void (_stdcall *GETCPUID)(struct ShortString *result, BYTE cpuCore); 

GETCPUID pGetSerial; 

HMODULE hWtsLib = LoadLibrary("HardwareIDExtractor.dll"); 
if (hWtsLib) { 
    ShortString serial; 
    pGetSerial = (GETCPUID)GetProcAddress(hWtsLib, "GetCPUID"); 
    pGetSerial(&serial, '1'); 
    char *str = malloc(serial.len + 1); // include space for the trailing \0 
    strlcpy(str, serial.data, serial.len); 
    str[serial.len] = '\0'; // drop in the trailing null 
} 

Ich werde das GetPartitionID als eine Übung für die Leser überlassen :-).

+0

Der C-Compiler weiß auch, wie er stdcall-Funktionen aufruft. Wenn der Delphi-Code erwartet, dass es der letzte Parameter ist, dann deklarieren Sie dies auch im C-Code. –

+0

Das "Funktionsergebnis" in diesem Szenario wird immer als letztes Element auf dem Stapel übergeben. Wenn es einen anderen Parameter gegeben hätte, wäre er in der gleichen Reihenfolge deklariert worden wie die Delphi-Deklaration * nach dem Ergebnisparameter. –

+0

Ich glaube nicht, dass '1' für cpuCore übergeben werden sollte, dann wäre der Parameter der DLL-Funktion wahrscheinlich ein Zeichen, kein Byte. Putting 0 oder 1 scheint es viel logischer zu sein. – mghie

1

Short ist nicht die gleiche wie PChar (char *). Es ist ein Array von Zeichen, wobei das erste Zeichen die Länge der Zeichenfolge ist. Für C ist es am besten, Sie verwenden PChar (char *) den ganzen Weg.

procedure GetCPUID (CpuCore: byte; CpuId: PChar; Len: Integer); stdcall; 
procedure GetPartitionID(Partition : PChar; PartitionId: PChar; Len: Integer); stdcall; 

typedef (_stdcall *GETCPUID)(BYTE, char*, int); 
typedef (_stdcall *GETPID)(PCHAR, char*, int); 
GETCPUID pGetSerial; 
GETPID pGetPID 

HMODULE hWtsLib = LoadLibrary("HardwareIDExtractor.dll"); 
if (hWtsLib){ 
pGetSerial = (GETCPUID)GetProcAddress(hWtsLib, "GetCPUID"); 
char *str = (char*) malloc(1024); 
pGetSerial((BYTE)"1", str, 1024); 

pGetPID= (GETPID)GetProcAddress(hWtsLib, "GetPartitionID"); 
char *str1 = (char*) malloc(1024); 
pGetPID("C:", str, 1024); 
+0

Ich habe nicht den Quellcode für diese DLL, so dass ich mein C-Programm an diese DLL anpassen kann und nicht umgekehrt. – Ampere

+0

Sie könnten immer einen Delphi-Wrapper schreiben, um die DLL aufzurufen, die PChar anstelle von ShortString zurückgibt. – RobS

Verwandte Themen