2016-03-05 6 views
3

Я работаю над проектом, который использует C - Ada language binding. Функция в C вызовет функцию на стороне Ada. Я хочу сделать вариационную функцию в Ada, которая может получать переменное количество аргументов, отправленных из функции C. Я также хотел отправить разные типы аргументов одновременно, например, int, char, enums и т. Д. Возможно ли иметь такой механизм?Функция Variadic в Ada (C - Ada binding)?

+1

Я не знаю, возможно ли это, Ада чрезвычайно строго типизирована, и функции vararg нарушают это. –

+4

№ Вам нужна отдельная подпрограмма Ada для каждого профиля вызова, который вы хотите создать. См. [Руководство пользователя GNAT] (https://gcc.gnu.org/onlinedocs/gnat_ugn/Calling-Conventions.html#index-C-130). .... подождите, если вы не используете GNAT, это может быть возможно; спросите своего поставщика компилятора. –

ответ

1

Вы не можете создать вариационную функцию в Ada. Вы можете имитировать вариационную функцию несколькими способами.

  1. Ada позволяет указать значения по умолчанию для функций и процедур. Не нужно всегда указывать значения параметров по умолчанию, если вы хотите использовать значения по умолчанию.
  2. Вы можете определить один или несколько параметров как вариантную запись.
+0

Изучается альтернативный подход [здесь] (http://stackoverflow.com/a/33093352/230513). – trashgod

0

Вы можете использовать 'адрес или пакет System.Address_To_Access_Conversions и' access (или 'unchecked_access) для создания адресов каждого элемента, который вы хотите передать.

type Address_Array is array (positive range <>) of System.address; 
    function C_Caller(Params : Address_Array) return Integer is begin return 0; end; 
    X, Y, Z, Result : Integer; 
begin 
    result := C_Caller(Address_Array'(x'address, y'address, z'address)); 

... тогда вам нужно будет импортировать фактическую функцию прагмы.

0

Нельзя использовать, чтобы вызвать любую вариационную функцию C от Ada портативным способом!

Одна из причин - некоторые ABI используют специальные способы/регистры для передачи значений поплавка. Этот средний компилятор C будет использовать эти регистры, из-за того, что заранее неизвестно, является ли аргумент float или нет. Компилятор Ada не будет использовать эти регистры (так как вы не можете поместить параметр float в объявление функции обертки Ada). В результате вы получите сбой, повреждение стека или любое другое неопределенное поведение.

AMD64 ABI В частности указывает:

% Ракс - с переменными аргументами передает информацию о количестве векторных регистров, используемых

% xmm0-% XMM1 - используется для передачи и возврата плавающей аргументы точки

Единственное портативное решение использует C-обертку с фиксированным числом параметров, а затем привязывает ее как обычно.