Как импортировать функцию из DLL, созданной в Delphi?

StackOverflow https://stackoverflow.com/questions/609970

  •  03-07-2019
  •  | 
  •  

Вопрос

Можете ли вы рассказать мне, как мне использовать следующие функции в моей программе на C.

Delphi DLL — Экспортированные функции:

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

У меня нет исходного кода для этой DLL, поэтому я должен адаптировать свою программу на C под эту DLL, а не наоборот.

Я делаю следующее и получаю ошибку

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:");
}

Спасибо

Это было полезно?

Решение

Поскольку у вас нет исходного кода DLL, вам придется проявить немного изобретательности в отношении C-стороны.Несмотря на то, что ShortString указан как результат функции, на самом деле ответственность за него лежит на звонящий чтобы указать место для размещения результата.Поскольку это функция stdcall, параметры передаются справа налево, то есть адрес результата ShortString передается последним.Чтобы это выровнялось, ему понадобится первый указанный параметр.Я сделаю первый API, GetCPUID.В C это может выглядеть примерно так:

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
}

Я оставлю GetPartitionID в качестве упражнения для читателя :-).

Другие советы

ShortString — это не то же самое, что PChar (char *).Это массив символов, первый символ которого соответствует длине строки.Для C лучше всего использовать PChar (char *).

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);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top