У меня есть файл сборки и правильно скомпилированы в ADA (простой мир Hello). Я хочу выполнить файл .o из c ++ с помощью taskspawn. Для этого я прочитал, что вы должны объявить в C ++ что-то вроде этого:
…
#include <taskLib.h>
/* Ada binder-generated main - ADA_MAIN is passed as a macro from the makefile */
extern void ADA_MAIN(void);
void UsrAppInit()
{
int stackSize = 0x80000;int spawnFlags = VX_FP_TASK;
/* MAIN_TASK_NAME is passed as a macro from the makefile */
char * mainTaskName = (char *) MAIN_TASK_NAME;
int priority = 100;
/* Spawn Ada environment task */
taskSpawn(mainTaskName, priority, spawnFlags, stackSize,
(FUNCPTR) ADA_MAIN, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
}
чтобы завершить процесс, я объявил ADA_MAIN как MACRO в make-файле (в моем случае это make-файл makefile.mk)
(MAIN_ADA pathOfmyADAexe и MAIN_TASK_NAME «процедура helloworld»)
но MACRO не распознаются в процессе, поэтому у меня ошибка при компиляции для MAIN_TASK_NAME и ADA_MAIN. Любое предложение о том, как я скучаю? Я тоже мог бы поступить по-другому, но как?
Я не знаю о твоих ADA_MAIN
, и вы не говорите нам, что ваш MACRO
так что о них немного сложно говорить. Кроме того, прошло некоторое время с тех пор, как я использовал VxWorks (и тогда нас поддерживали, поэтому у нас был доступ к кросс-компилятору, который сделал сборку для нас: и наша основная программа была в Аде).
Тем не менее, ваша проблема сводится к создание программы с компонентами Ada, где основной программы нет в Ada.
Ада программы нужны разработка. Это процесс, который вызывает все компоненты библиотеки времени выполнения и организует их инициализацию в правильном порядке. Какие компоненты вы спросите? ну, например, есть очевидное Ada.Text_IO
; и есть менее очевидные вещи, такие как обработка исключений.
Код разработки генерируется с использованием gnatbind.
Учитывая это hello.adb
with Ada.Text_IO;
procedure Hello is
begin
Ada.Text_IO.Put_Line ("hello!");
end Hello;
вам действительно нужно предоставить спецификацию, иначе компилятор сгенерирует имя компоновщика, например __ada_hello
; взять под контроль hello.ads
,
procedure Hello with
Export,
Convention => C,
External_Name => "hello";
Вы будете использовать кросс-компиляцию. Компоненты имеют префикс имени цели, например powerpc-wrs-vxworks-gnatmake
, arm-eabi-gnatbind
, но я просто буду использовать голое имя компонента ниже.
$ gnatmake -c hello.adb
который генерирует hello.o
, hello.ali
(если бы программа была более сложной, она также скомпилировала бы закрытие).
Теперь свяжите:
$ gnatbind -n -Lhello -static hello.ali
где
-n
: основная программа не в Аде-Lhello
: adainit
, adafinal
переименованный helloinit
, hellofinal
-static
: уверен, что VxWorks не поддерживает общие библиотеки?порождающий b~hello.ads
, b~hello.adb
(в зависимости от версии компилятора ~
может быть заменен, например, двойное подчеркивание). Обобщение:
$ gnatmake -c b~hello.adb
Теперь звонить из C ++. вам нужно сообщить компилятору о символах в коде Ada, например, hello.h
:
extern "C" {
void helloinit();
void hellofinal();
void hello();
}
а затем основная программа в main.cc
:
#include "hello.h"
int main() {
helloinit();
hello();
hellofinal();
}
который оставляет вас с компиляцией C ++ и связью, которая требует времени выполнения Ada в libgnat.a
и (для задач) libgnarl.a
и, конечно, очень зависит от компилятора и установки: здесь, на хосте macOS, я использовал
$ g++ main.cc b~hello.o hello.o /opt/gcc-8.1.0/lib/gcc/x86_64-apple-darwin15/8.1.0/adalib/libgnat.a
$ ./a.out
hello!
Переводя это в контекст VxWorks, я бы сказал, что вы позвоните helloinit()
из вашей основной программы (вам, вероятно, не понадобится hellofinal()
) и передать hello
в taskSpawn()
вместо вашего ADA_MAIN
,
Других решений пока нет …