如何在Delphi中与包含va_args的C回调定义接口



我想在Delphi中集成的C库包含以下调试日志回调函数定义:

typedef void (*libfoo_log_cb)(void *data, int level, const char *fmt, va_list args);

Delphi中回调函数的签名如下:

procedure LibFooLog( data: Pointer; level: Integer; fmt: PAnsiChar; args: Pointer ); cdecl;

当C库触发回调函数时;fmt";字符串显然包含许多printf说明符,如"%s";等等。我如何从";fmt";并且va列表";args";在德尔福?也许我可以使用Windows的MSVCRT运行时来进行格式化,但我该如何将参数映射到它?

C有一个名为va_list的结构。Args应该指向一个实例。我对delphi了解不多,但您可以用C编写一个函数,返回一个va_list并将其用作args参数。您可能需要分配它,而不是使用va_list的正常堆栈分配。

可以让Windows系统的C运行库进行字符串格式化。如果(并且仅当(接受回调的C库也链接到同一个C运行库,这应该有效。

示例代码:

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;

最新更新