Я пытаюсь освободить запись с тегами Ada, выделенную кучей, из cpp. Я использовал код AdacoreU в качестве отправной точки.
Я получаю следующую ошибку при запуске кода ниже.
20
double free or corruption (out)
raised PROGRAM_ERROR : unhandled signal
Я слишком много обдумываю? Нужен ли мне механизм освобождения на основе Ады.
Какова моя настоящая конечная цель? Я хотел бы использовать динамические библиотеки для создания инфраструктуры плагинов, где каждая библиотека является собственной фабрикой для данного типа. Что-то вроде boost dll, но с динамическими библиотеками на основе ada.
Модифицированный код ниже:
main.cpp
1 #include <iostream>
2 #include "animal.h"
3
4 extern "C" {
5 void adainit (void);
6 void adafinal (void);
7 Animal* new_animal();
8 void del_animal(Animal *);
9 }
10
11 int main(void) {
12 adainit();
13 Animal* A = new_animal();
14 std::cout << A->age() << std::endl;
15 //delete A;
16 del_animal(A);
17 adafinal();
18 return 0;
19 };
Алиб.объявления
1
2 with Interfaces.C;
3
4 package ALib is
5
6 type Animal is tagged record
7 The_Age : Interfaces.C.int;
8 end record;
9 pragma Convention (CPP, Animal);
10
11 type Animal_Class_Access is access Animal'Class;
12
13 function New_Animal return access Animal'Class;
14 pragma Export(CPP, New_Animal);
15
16 procedure Del_Animal (this : in out Animal_Class_Access);
17 pragma Export(CPP, Del_Animal);
18
19 function Age(X : Animal) return Interfaces.C.int;
20 pragma Export(CPP, Age);
21
22 end ALib;
alib.adb
1 with ada.unchecked_deallocation;
2
3 package body ALib is
4
5 function New_Animal
6 return access Animal'Class is
7 begin
8 return new Animal'(The_Age => 20);
9 end New_Animal;
10
11
12 procedure Del_Animal (this : in out Animal_Class_Access) is
13 procedure Free is new ada.unchecked_deallocation(Animal'Class, Animal_Class_Access);
14 begin
15 Free(this);
16 --null;
17 end Del_Animal;
18
19 function Age(X : Animal)
20 return Interfaces.C.int is
21 begin
22 return X.The_Age;
23 end Age;
24
25 end ALib;
~
другие ресурсы, используемые в качестве отправной точки
3.11.3.5 Взаимодействие с C++ на уровне класса
Что я пытался:
Что я ожидал:
Я ожидал очистить объекты кучи Ады от Ады.
Проблема заключается в параметре in out
для Del_Animal
и его сопоставлении с миром C.
Ваше намерение с Del_Animal
состоит в том, что он должен вести себя как Ada.Unchecked_Deallocation
, другими словами, чтобы параметр был установлен в null
(или 0
!) после вызова, но это означает, что вам нужно передать фактический адрес.
То есть,
void del_animal(Animal**);
называется как
del_animal(&A);
См. ARM B3(68).
Насколько я знаю, это способ сделать это. Что вам показалось бы «лучше»?
Нет ничего особенного, что показалось бы мне лучше. Я просто предположил, что делаю что-то нетипичным образом и что могу добиться «лучших» результатов, следуя какому-то другому образцу.
Есть ли лучший способ сделать это?