Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何从Delphi中创建的DLL导入函数?_C_Delphi_Dll_Function - Fatal编程技术网

C 如何从Delphi中创建的DLL导入函数?

C 如何从Delphi中创建的DLL导入函数?,c,delphi,dll,function,C,Delphi,Dll,Function,你能告诉我如何在我的C程序中使用以下函数吗 Delphi DLL-导出的函数: function GetCPUID (CpuCore: byte): ShortString; stdcall; function GetPartitionID(Partition : PChar): ShortString; stdcall; 我没有该DLL的源代码,所以我必须使我的C程序适应该DLL,而不是相反 我执行以下操作并得到错误信息 typedef char* (_stdcall *GETCPUID)(

你能告诉我如何在我的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:");
}

谢谢

短字符串与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);

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);

由于您没有DLL的源代码,因此需要在C端进行一些创新。即使短字符串被列为函数结果,调用方实际上也有责任提供放置结果的位置。因为这是一个stdcall函数,所以参数是从右到左传入的,这意味着短字符串结果的地址是最后传入的。要使其对齐,它需要列出第一个参数。我将执行第一个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作为练习留给读者:-)。

因为您没有DLL的源代码,所以您需要在C端进行一些创新。即使短字符串被列为函数结果,调用方实际上也有责任提供放置结果的位置。因为这是一个stdcall函数,所以参数是从右到左传入的,这意味着短字符串结果的地址是最后传入的。要使其对齐,它需要列出第一个参数。我将执行第一个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作为练习留给读者:-)。

您到底得到了什么错误?如果没有这些信息,就很难提供帮助。程序编译并运行,但调用DLL函数时会崩溃。您得到的确切错误是什么?如果没有这些信息,就很难提供帮助。程序编译并运行,但调用DLL函数时会崩溃。我没有该DLL的源代码,因此我可以将我的C程序改编为该DLL,而不是反过来。你可以编写一个Delphi包装器来调用返回PChar的DLL,而不是ShortStringI。我没有源代码为该DLL编写代码,以便我可以使我的C程序适应该DLL,而不是相反。您可以编写一个Delphi包装器来调用返回PChar的DLL,而不是ShortStringC编译器知道如何调用stdcall函数。如果Delphi代码希望它是最后一个参数,那么也在C代码中声明它。在这个场景中,“函数结果”总是作为堆栈上的最后一项传递。如果有另一个参数,它将按照与结果参数后的Delphi声明相同的顺序声明。我认为不应将“1”传递给cpuCore,那么DLL函数的参数可能是字符,而不是字节。将0或1放在那里似乎更符合逻辑。我只是在遵循OP的示例。由他们来确保参数是正确的。此外,这并不是问题的焦点。是的。CpuCore的参数是0表示第一个CPU,1表示第二个CPU,依此类推。。。。对于分区,应该有“C”或“D”或…C编译器也知道如何调用stdcall函数。如果Delphi代码希望它是最后一个参数,那么也在C代码中声明它。在这个场景中,“函数结果”总是作为堆栈上的最后一项传递。如果有另一个参数,它将按照与结果参数后的Delphi声明相同的顺序声明。我认为不应将“1”传递给cpuCore,那么DLL函数的参数可能是字符,而不是字节。将0或1放在那里似乎更符合逻辑。我只是在遵循OP的示例。由他们来确保参数是正确的。此外,这并不是问题的焦点。是的。CpuCore的参数是0表示第一个CPU,1表示第二个CPU,依此类推。。。。对于分区,应该有“C”或“D”或。。。。