Как импортировать функцию из DLL, созданной в Delphi? - PullRequest
1 голос
/ 04 марта 2009

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

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

Спасибо

Ответы [ 2 ]

7 голосов
/ 04 марта 2009

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

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 в качестве упражнения для читателя: -).

1 голос
/ 04 марта 2009

ShortString не совпадает с PChar (char *). Это массив символов 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...