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

この関数は、可変引数リストを持つ別の関数へのポインタを返します。これらの 1 つを次のように宣言します。

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これは、C に相当するものが存在しないマネージド Delphi 型であるため、使用できません。

また、エラー関数のプロトタイプには void の戻り値があります。ポインターを返していますが、これはエラーです。

より大きな問題は、Delphi で可変数の引数を受け取る C スタイルの関数を簡単に実装できないことです。このような関数を宣言して呼び出すことはできますが、実装することはできません。これは、可変引数を持つそのような関数は外部関数でなければならないことを意味します。

これで、独自のアセンブラー ルーチンを記述して、変数の引数を完全にオフにすることができます。しかし、それは私がとる道ではありません。関数を C で記述し、それを .obj ファイルにコンパイルします。このファイルは、.obj を使用して Delphi プログラムにリンクできます$LINK

実際に変数の引数を読み取る必要がない場合は、次のように無視できます。

TErrorMessageHandler = procedure(Name: PAnsiChar); cdecl;

次の変更を行ったことに注意してください。

  1. 型名をT標準の前に付けるように変更します。
  2. Nameパラメータの型を修正しました。
  3. C 宣言に一致するように関数からプロシージャに変更されました。
  4. varargsDelphi で実装できない を削除したため、追加のパラメータは無視されます。

次に、インポートされた関数は次のようになります。

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 に答える