Как удалить запись Ada из CPP

Я пытаюсь освободить запись с тегами 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++ на уровне класса

Что я пытался:

  • Использовали различные комбинации типа и типа доступа при попытке создать процедуру Free.
    • Животное, тип Animal_Access — доступ к животному
    • Animal'Class, тип Animal_Class_Access — это доступ к Animal'Class
    • Animal, тип Animal_Access — это класс доступа Animal'Class
  • В какой-то момент у меня сложилось впечатление, что я должен использовать системный адрес для указателей на объект Animal как часть возврата New_Animal и как аргумент для Del_Animal.

Что я ожидал:

Я ожидал очистить объекты кучи Ады от Ады.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
95
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема заключается в параметре in out для Del_Animal и его сопоставлении с миром C.

Ваше намерение с Del_Animal состоит в том, что он должен вести себя как Ada.Unchecked_Deallocation, другими словами, чтобы параметр был установлен в null (или 0!) после вызова, но это означает, что вам нужно передать фактический адрес.

То есть,

void del_animal(Animal**);

называется как

del_animal(&A);

См. ARM B3(68).

Есть ли лучший способ сделать это?

shakeysailing 02.12.2022 02:21

Насколько я знаю, это способ сделать это. Что вам показалось бы «лучше»?

Simon Wright 02.12.2022 12:53

Нет ничего особенного, что показалось бы мне лучше. Я просто предположил, что делаю что-то нетипичным образом и что могу добиться «лучших» результатов, следуя какому-то другому образцу.

shakeysailing 03.12.2022 21:21

Другие вопросы по теме