1

Can you tell me how do i use the following functions in my C program.

Delphi DLL - Exported functions :

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

I don't have the source code for that DLL so I must adapt my C program to that DLL and not the other way around.

I do the following and get error

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

Thanks

2
  • What error are you getting exactly? Without that information it is hard to help. Commented Mar 4, 2009 at 14:49
  • The program compile and runs but it crashes when calling the DLL function. Commented Mar 5, 2009 at 9:04

2 Answers 2

7

Since you don't have the source to the DLL, you'll need to get a little creative on the C side of things. Even though the ShortString is listed as the function result, it is actually the responsibility of the caller to provide a location in which to place the result. Because this is a stdcall function, parameters are passed in from right to left, so that means that the address of the ShortString result is passed in last. To get this to line up, it will need to the first parameter listed. I'll do the first API, GetCPUID. In C, it might look something like this:

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
}

I'll leave the GetPartitionID as an exercise for the reader :-).

Sign up to request clarification or add additional context in comments.

5 Comments

The C compiler knows how to call stdcall functions, too. If the Delphi code is expecting it to be the last parameter, then declare it that way in the C code, too.
The "function result" in this scenario is always passed as the last item on the stack. If there had been another parameter, it would have been declared in the same order as the Delphi declaration after the result param.
I don't think that '1' should be passed for cpuCore, then the parameter of the DLL function would probably be a char, not a byte. Putting 0 or 1 there seems to be much more logical.
I was merely following the example of the OP. It is up to them to ensure that the parameter is correct. Besides, that wasn't the focus of what was being asked.
Yes. The parameter for CpuCore is 0 for first CPU, 1 for the second and so on.... For partition there should be "C" or "D" or....
1

ShortString is not the same as PChar (char *). It is an array of char with the first char being the length of the string. For C it is best you use PChar (char *) all the way.

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

2 Comments

I don't have the source code for that DLL so I can adapt my C program to that DLL and not the other way around.
You could always write a Delphi wrapper to call the DLL returning PChar instead of ShortString

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.