5

我正在将视频编码器 DLL 的 C 头文件转换为 Delphi Pascal。

我遇到了一些使用以下功能的访问冲突问题,需要帮助解决这个问题:

h264venc_tt * MC_EXPORT_API h264OutVideoNew(
  void * (MC_EXPORT_API * get_rc)(const char* name),
  const struct h264_v_settings * set,
  int32_t options,
  int32_t CPU,
  int32_t frame0,
  int32_t nframes);

注意:MC_EXPORT_API = cdecl

get_rc 声明如下:

// resource functions dispatcher
void * MC_EXPORT_API get_rc(const char* name)
{
  if (!strcmp(name, "err_printf"))
    return (void*) error_printf;
  else if (!strcmp(name, "prg_printf"))
    return (void*) progress_printf;
  else if (!strcmp(name, "wrn_printf"))
    return (void*) warn_printf;
  else if (!strcmp(name, "inf_printf"))
    return (void*) info_printf;
  return NULL;
}

此函数返回指向另一个具有变量参数列表的函数的指针。其中之一被声明为:

void error_printf(const char * fmt, ...)
{
  char lst[256];
  va_list marker;
  va_start(marker,fmt);
  vsprintf(lst,fmt,marker);
  va_end(marker);
  printf("%s\n", lst);
}

我已经将这个函数调用和 get_rc 翻译成这个 Delphi Pascal 代码:

PErrorMessageHandler = function (const Name: String): Pointer; cdecl varargs;

function h264OutVideoNew(
  get_rc: PErrorMessageHandler;
  settings: Ph264_v_settings;
  options: int32;
  CPU: int32;
  frame0: int32;
  nFrames: int32
): Pointer; cdecl; external 'mc_enc_avc.dll' index 4;

不幸的是,我不知道如何实现上面显示的 C 风格方法 error_printf。谁能帮我指出正确的方向?我也很好奇我是否正确实现了其他功能,因为当我尝试调用该h264OutVideoNew()函数时遇到访问冲突。

PS!我没有在这篇文章中包含打包的记录Th264_v_settings/P_h264_v_settings因为这很长而且不是真正的问题。

4

1 回答 1

6

类型的 AC 参数char*是指向以空字符结尾的 8 位字符数组的指针。在 Delphi 中,等效类型是PAnsiChar. 您不能使用string,因为它是托管的 Delphi 类型,在 C 中没有等价物。

此外,错误函数原型具有 void 返回值。您正在返回一个指针,这是一个错误。

您遇到的更大问题是,您无法在 Delphi 中轻松实现接收可变数量参数的 C 风格函数。你可以声明和调用这样一个函数,但你不能实现一个。这意味着这样一个带有可变参数的函数必须是一个外部函数

现在,您可以编写自己的汇编程序来填充变量参数。但是,这不是我会采取的路线。我会用 C 编写函数,然后将其编译为 .obj 文件,该文件可以使用 .obj 链接到您的 Delphi 程序中$LINK

如果您实际上不需要读取变量参数,则可以像这样忽略它们:

TErrorMessageHandler = procedure(Name: PAnsiChar); cdecl;

请注意,我进行了以下更改:

  1. 将类型名称更改T为标准前缀。
  2. 更正了Name参数的类型。
  3. 从函数更改为过程以匹配 C 声明。
  4. 删除了varargs我们无法在 Delphi 中实现的,因此忽略了附加参数。

然后您导入的函数将如下所示:

function h264OutVideoNew(
  get_rc: TErrorMessageHandler;
  settings: Ph264_v_settings;
  options: int32;
  CPU: int32;
  frame0: int32;
  nFrames: int32
): Pointer; cdecl; external 'mc_enc_avc.dll' index 4;

然后你可以像这样实现错误回调函数:

procedure error_printf(Name: PAnsiChar); cdecl;
begin
  // do stuff here
end;
于 2013-02-24T11:38:55.693 回答