Call variadic C function by its memory address in Delphi
-
23-09-2019 - |
Question
Suppose I have a function in C++ in which I call it using a pointer to its memory address, with typedef
. Now, how can I do the same thing in Delphi?
For example:
typedef void (*function_t)(char *format, ...);
function_t Function;
Function = (function_t)0x00477123;
And then, I can call it with: Function("string", etc);
.
Is there any way to do this without using Assembly instructions, in Delphi?
Note that it is a variadic parameters function.
Solution
An idiomatic translation for this:
typedef void (*function_t)(char *format, ...);
function_t Function;
Function = (function_t)0x00477123;
Is this:
type
TFunction = procedure(Format: PAnsiChar) cdecl varargs;
var
Function: TFunction;
// ...
Function := TFunction($00477123);
The 'cdecl varargs' is required to get the C calling convention (where the caller pops the stack) and the variadic argument support (which is only supported with the C calling convention). Varargs is only supported as a means for calling C; there is no built-in support in Delphi for implementing variadic parameter lists in the C style. Instead, there is a different mechanism, used by the Format procedure and friends:
function Format(const Fmt: string; const Args: array of const): string;
But you can find out more about that elsewhere.
OTHER TIPS
program Project1;
type
TFoo = procedure(S: String);
var
F: TFoo;
begin
F := TFoo($00477123);
F('string');
end.
Of course, if you just run the above you'll get a runtime error 216 at address $00477123.
Yes, Delphi supports function pointers. Declare it like this:
type MyProcType = procedure(value: string);
Then declare a variable of type MyProcType and assign the address of your procedure to it, and you can call it the same way you would in C.
If you want a pointer to a method of an object instead of a standalone procedure or function, add "of object" to the end of the function pointer declaration.