Вызов сканфа из Ады - PullRequest
       28

Вызов сканфа из Ады

2 голосов
/ 08 января 2012

Как вы называете scanf из Ada?То есть, предположительно, с соответствующей декларацией импорта pragma, но как бы это объявление выглядело?

(меня интересует, как вызывать функции C из более недисциплинированного множества из Ada, а не как разбирать строки вПоэтому я не ищу чистого решения Ada. Моя настройка - Gnat, Ubuntu Linux, x64, если это имеет значение.)

Ответы [ 2 ]

2 голосов
/ 16 января 2012

Один из обходных путей - объявить несколько невариантных функций-оболочек в 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);
}

, а затем объявить перегруженную функцию scan ()в Аде с pragma Import.

Таким образом, вы не пытаетесь вызывать переменные функции из Ады;все преобразования в фиксированные переменные происходят на стороне C.И пока все оболочки написаны правильно, вы получаете больше проверок типов, чем при прямом вызове scanf().

Вам просто нужна отдельная оболочка для каждого набора типов parmaeter, который вы хотите передать.

Это, вероятно, нормально, если у вас всего несколько звонков, но оно плохо масштабируется.

2 голосов
/ 08 января 2012

В этой статье указывается, что

Ада не может объявить функцию, которая принимает разное количество параметров разных типов.Можно объявить набор функций «printf», которые принимают строку, строку и целое число, строку и число с плавающей запятой, строку и 2 целых числа и т. Д., А затем объявить каждую из них как Import (C)2.Но для этого требуется множество объявлений, по одному для каждого вида использования в прикладной программе, так что это на самом деле не практично.

То же самое относится и к scanf(), что в Ada 2012имеет дополнительный бонус, позволяющий вам выбирать между out и access спецификациями параметров (в более ранних версиях вам приходилось использовать access, потому что функциям не разрешалось иметь out параметры).

Кроме того, я не верю, что требуется, чтобы компилятор C использовал те же механизмы передачи параметров для функций с переменными числами, что и для обычных функций ( ссылка намекает на это, и я помню, но могу 'Теперь можно найти недавний разговор по этим строкам).

Тем не менее, вот пример, который, кажется, прекрасно работает на Mac OS X с GCC 4.6.0:

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 в параметре формата!)

...