我正在try 让Ada代码编译成可在C中调用的DLL,到目前为止,我已经设法使其适用于简单类型,如整数,但对于更复杂的类型,如数组或记录/ struct ,我遇到了困难.

下面是我的记录/ struct 的Ada代码.它是一个动态库,我使用命令"gprBuild-p../Math.gpr-p"将其编译为DLL:

person.adb
with Interfaces.C; use Interfaces.C;

package body Person is

   function Set_Age_To_Five(P : Person_Record) return Person_Record is
      Result : Person_Record;
   begin
      Result := P;
      Result.Age := 5;
      return Result;
   end Set_Age_To_Five;

end Person;

Person.ads

with Interfaces.C; use Interfaces.C;

package Person is

   type Person_Record is record
      Name    : String(1 .. 100);
      Age     : Interfaces.C.int;
      Address : String(1 .. 100);
   end record with Convention => C_Pass_By_Copy;

   function Set_Age_To_Five(P : Person_Record) return Person_Record;
   pragma Export (C, Set_Age_To_Five, "Set_Age_To_Five");

end Person;

Math.gpr

library project Math is
    for Languages use ("Ada");
    for Library_Name use "Person";
    for Source_Dirs use ("src");
    for Object_Dir use "obj";
    for Library_Dir use "lib";
    for Library_Kind use "Dynamic";
end Math;

然后我有一个C头文件math.h:

#ifndef MATH_H
#define MATH_H

#ifdef __cplusplus
extern "C"
#endif

typedef struct {
    char Name[101];
    int Age;
    char Address[101];
} Person_Record;

Person_Record Set_Age_To_Five(Person_Record P);

#ifdef __cplusplus

#endif

#endif /* MATH_H */

最后是我的C代码:

#include <stdio.h>
#include "math.h"

int main() {
    Person_Record p, q, r;

    // Initialize the person record
    snprintf(p.Name, sizeof(p.Name), "John");
    p.Age = 25;
    snprintf(p.Address, sizeof(p.Address), "123 Main St");

    // Call the Set_Age_To_Five function from the DLL
    q = Set_Age_To_Five(p);

    // Print the modified person record
    printf("Name: %s\n", q.Name);
    printf("Age: %d\n", q.Age);
    printf("Address: %s\n", q.Address);

    return 0;
}

这在执行时应该返回

Name: John
Age: 5
Address: 123 Main St

相反,它的回归:

Name: John
Age: 25
Address: 123 Main St

我try 过通过变量传递,通过引用传递.在ADA中使用约定C和约定传递c.

推荐答案

数据 struct 的Ada到C互操作通常是使用指针完成的,而且可能更可靠.

有:

procedure Set_Age_To_Five (P : in out Person_Record);
pragma Export (C, Set_Age_To_Five, "Set_Age_To_Five");

procedure Set_Age_To_Five (P : in out Person_Record) is
begin
   P.Age := 5;
end Set_Age_To_Five;

C:

void Set_Age_To_Five(Person_Record *P);
Set_Age_To_Five(&p);

我确实理解这比从ADA返回新 struct 要方便得多,但ADA返回值的方式似乎有问题.这可能与ADA使用与C不同的"按值传递"模型有关.

C++相关问答推荐

传递给空闲的无效地址0x71 db7 cb5e0:未分配值

带双指针的2D数组

为什么写入系统调用打印的字符数不正确?

exit(EXIT_FAILURE):Tcl C API类似功能

#If指令中未定义宏?

自定义变参数函数的C预处置宏和警告 suppress ?

如何在c++中包装返回空*的函数

使用错误的命令执行程序

用C语言计算文本文件中的整数个数

将字符串数组传递给C中的函数:`str[dim1][str_size]`vs`*str[dim1]`

C语言中浮点数的取整方式浮点数尾数超过23位时如何取整剩余部分

C:Assignment中的链表赋值从指针目标类型中丢弃‘const’限定符

为什么我的二叉树删除删除整个左部分的树?

隐藏测试用例无法在c程序中计算位数.

某些EAX值的不同调用方的CPUID结果不一致

GETS()在C++中重复它前面的行

使用共享变量同步多线程 C 中的函数

使用邻接表创建图

C23 中是否有 __attribute__((nonnull)) 的等效项?

无法在 C 中打开文本文件,我想从中读取文本作为数据并将其写入数组