2

Ada から scanf を呼び出すにはどうすればよいですか? つまり、おそらく適切なプラグマのインポート宣言を使用しますが、宣言はどのようになりますか?

(文字列自体を解析する方法ではなく、より手に負えないさまざまなC関数をAdaから呼び出す方法に興味があるため、純粋なAdaソリューションを探しているわけではありません。私のセットアップはGnat、Ubuntu Linux、x64です。違います。)

4

2 に答える 2

2

この論文はそれを指摘している

Adaには、さまざまなタイプのさまざまな数のパラメーターを受け取る関数を宣言する方法がありません。文字列、文字列と整数、文字列と浮動小数点数、文字列と2つの整数などを受け取る一連の「printf」関数を宣言し、それぞれをインポート(C)として宣言することができます。 2.2。しかし、これには多くの宣言が必要であり、アプリケーションプログラムでの使用の種類ごとに1つずつあるため、実際には実用的ではありません。

同じことが当てはまります。Ada2012では、パラメーターの仕様からscanf()選択できるという追加のボーナスがあります(以前のリビジョンでは、関数にパラメーターを含めることが許可されていなかったため、を使用する必要がありました)。outaccessaccessout

さらに、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フォーマットパラメータのについてはよくわかりません!)

于 2012-01-08T17:40:06.673 に答える
2

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()

渡したいパラメータ タイプのセットごとに個別のラッパーが必要です。

呼び出しが少ない場合はおそらく問題ありませんが、スケーリングがうまくいきません。

于 2012-01-16T04:06:08.267 に答える