1

g ++を使用して64ビットオペレーティングシステムを作成していますが、次のような可変個引数関数があります。

void DbgPrint(const char *fmt, ...);

これはprintfのように動作します。ここでの問題は、g++がSystemV ABIに従うため、RDI、RSI、RDX、RCX、R8、R9の最初の引数を渡し、残り(存在する場合)をスタックにプッシュすることです。

古いstdarg.hマクロva_start、va_argなどをcdeclで使用することは、va_argがスタック上の次の要素を取得するだけなので、すべて非常に簡単でした。しかし、これらのマクロは7番目の引数までまったく機能しません。

考えられる唯一の解決策は(IMHO)です。

  • g++にcdecl関数を作成させる。__属性__((cdecl))が意図的かつ明確に無視されているように強調表示されているため、これは不可能のようです。
  • 引数を渡す新しい方法で機能する新しいマクロのセットを用意します。

(私は実際にWinに取り組んでいるので、それらの実装をチェックするためのglibcヘッダーがありません)。

解決策を持っている人はいますか?前もって感謝します。

4

1 に答える 1

2

stdarg.h は libc の一部ではなく、コンパイラ自体の一部です。したがって、g++ を使用している場合は、これを処理するために付属の stdarg.h が必要です。通常、システムがインクルードする前に自動的に検索される gcc のプライベート インクルード ディレクトリにインストールされます。

gcc の stdarg.h を見ると、va_ マクロはすべて、コンパイラーが魔法のように処理方法を知っている __builtin 関数にマップするように定義されていることがわかります。

typedef __builtin_va_list __gnuc_va_list;
typedef __gnuc_va_list va_list;

#define va_start(v,l)   __builtin_va_start(v,l)
#define va_end(v)   __builtin_va_end(v)
#define va_arg(v,l) __builtin_va_arg(v,l)

これらのビルトインはすべて、ターゲット ABI で使用される呼び出し規約を理解しています。

于 2012-03-26T17:21:09.073 に答える