A C library that I would like to integrate in Delphi contains the following debug log call back function definition:
typedef void (*libfoo_log_cb)(void *data, int level, const char *fmt, va_list args);
The signature of my callback function in Delphi looks like this:
procedure LibFooLog( data: Pointer; level: Integer; fmt: PAnsiChar; args: Pointer ); cdecl;
When the callback function is triggered by the C library the "fmt" string obviously contains a lot of printf specifiers like "%s" etc. How can I assemble the string from "fmt" and the va-list "args" in Delphi? Maybe I can use the MSVCRT run-time of Windows to do the formatting but how would I map the arguments to it?
CodePudding user response:
C has a struct called va_list. Args should point to a instance. I don't know much about delphi, but you can write a function in C, that returns a va_list and use it as the args argument. You may need to allocate it instead of using the normal stack allocation of a va_list.
CodePudding user response:
There is a possibility to let the Windows system's C runtime library do the string formatting. This should work if (and only if) the C library that accepts the callback also is linked to the same C runtime library.
Example Code:
function vsnprintf( buffer: PAnsiChar; count: LongWord; format: PAnsiChar; argptr: Pointer ): Integer; cdecl; external 'msvcrt.dll';
procedure LibFooLog( data: Pointer; level: Integer; fmt: PAinsiChar; args: Pointer ); cdecl;
var
Buffer: array[0..4096] of AnsiChar;
Count: Integer;
begin
Count := vsnprintf(@Buffer[0], SizeOf(Buffer), fmt, args);
if Count > 0 then
begin
// cast the output to string with AnsiString(Buffer) and do something with it
end;
end;