Ada から scanf を呼び出すにはどうすればよいですか? つまり、おそらく適切なプラグマのインポート宣言を使用しますが、宣言はどのようになりますか?
(文字列自体を解析する方法ではなく、より手に負えないさまざまなC関数をAdaから呼び出す方法に興味があるため、純粋なAdaソリューションを探しているわけではありません。私のセットアップはGnat、Ubuntu Linux、x64です。違います。)
Ada から scanf を呼び出すにはどうすればよいですか? つまり、おそらく適切なプラグマのインポート宣言を使用しますが、宣言はどのようになりますか?
(文字列自体を解析する方法ではなく、より手に負えないさまざまなC関数をAdaから呼び出す方法に興味があるため、純粋なAdaソリューションを探しているわけではありません。私のセットアップはGnat、Ubuntu Linux、x64です。違います。)
この論文はそれを指摘している
Adaには、さまざまなタイプのさまざまな数のパラメーターを受け取る関数を宣言する方法がありません。文字列、文字列と整数、文字列と浮動小数点数、文字列と2つの整数などを受け取る一連の「printf」関数を宣言し、それぞれをインポート(C)として宣言することができます。 2.2。しかし、これには多くの宣言が必要であり、アプリケーションプログラムでの使用の種類ごとに1つずつあるため、実際には実用的ではありません。
同じことが当てはまります。Ada2012では、パラメーターの仕様からscanf()
選択できるという追加のボーナスがあります(以前のリビジョンでは、関数にパラメーターを含めることが許可されていなかったため、を使用する必要がありました)。out
access
access
out
さらに、Cコンパイラが可変個引数関数に対して通常の関数と同じパラメータ受け渡しメカニズムを使用する必要があるとは思わない(参照はこれを示唆しており、思い出しますが、最近の会話を見つけることができません)これらの行で)。
そうは言っても、GCC4.6.0を搭載したMacOSXで正常に動作するように見える例を次に示します。
with Ada.Text_IO; use Ada.Text_IO;
with Interfaces.C; use Interfaces.C;
procedure Variadic is
function Scanf (Fmt : char_array; Result : access int) return int;
pragma Import (C, Scanf, "scanf");
Status : int;
Result : aliased int;
begin
Status := Scanf (To_C ("%d\n"), Result'Access);
Put_Line ("status: " & int'Image (Status));
if Status = 1 then
Put_Line ("result: " & int'Image (Result));
end if;
end Variadic;
(\n
フォーマットパラメータのについてはよくわかりません!)
1 つの回避策は、C で複数の非可変個のラッパー関数を宣言し、それらを Ada にインポートすることです。
例えば:
int scanf_i(const char *format, int *i_ptr) {
return scanf(format, i_ptr);
}
int scanf_d(const char *format, double *d_ptr) {
return scanf(format, d_ptr);
}
次に、Ada でオーバーロードされた scan() 関数を で宣言しpragma Import
ます。
この方法では、Ada から可変個引数関数を呼び出そうとしていません。すべての固定から可変長への変換は C 側で行われます。また、すべてのラッパーが正しく記述されている限り、 を直接呼び出すよりも多くの型チェックを取得できますscanf()
。
渡したいパラメータ タイプのセットごとに個別のラッパーが必要です。
呼び出しが少ない場合はおそらく問題ありませんが、スケーリングがうまくいきません。