将记录数组传递给ADA中的C例程

时间:2014-04-01 16:01:59

标签: c ada

我想将一组记录从ADA程序传递给C例程。 C代码如下所示:

dongo.h

typedef struct _RFC_CONNECTION_PARAMETER
{
    const char * name;
    const char * value; 
} RFC_CONNECTION_PARAMETER;

void  open(RFC_CONNECTION_PARAMETER const * connectionParams,  int n);

dongo.c:

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

void  open(RFC_CONNECTION_PARAMETER const * connectionParams, int n)
{
    int i;
    printf("Hello\n");
    for(i=0; i<n; i++)
    {
        printf("%d : %s = %s\n", i,connectionParams[i].name,connectionParams[i].value);      
    }
}

ADA代码是:

with dongo_h; use dongo_h;
with Interfaces.C; use Interfaces.C;

with System;

procedure main is
   type RFC_CONNECTION_PARAMETER_PTR is access all RFC_CONNECTION_PARAMETER;

   type RFC_CONNECTION_PARAMETER_ARRAY      is array (Interfaces.C.int range <>) of RFC_CONNECTION_PARAMETER_PTR;
   pragma Convention (C, RFC_CONNECTION_PARAMETER_ARRAY);
   par :   RFC_CONNECTION_PARAMETER_ARRAY(1..2);
   begin
      par(1) := new RFC_CONNECTION_PARAMETER;
      par(2) := new RFC_CONNECTION_PARAMETER;
      par(1).name       := New_String("ABC");
      par(1).value      := New_String("123");   
      par(2).name       := New_String("ABC");
      par(2).value      := New_String("456");  
      open(par'Address,2);
end;

Mingw64-Toolchain的Makefile是:

main.exe : main.adb dongo.h dongo.c
    gcc -fdump-ada-spec  dongo.h
    gcc -c -m64 dongo.c
    gnatmake  -c main.adb 
    gnatbind -x main.ali  
    gnatlink -M -v  main.ali   -lmingw32  dongo.o  -o main.exe

程序会产生奇怪的随机输出,这表明参数传递根本不起作用。在没有成功地在互联网上寻找全面的例子后,我在这里发布这个问题,希望有人能解释我如何正确地完成参数传递。

提前致谢。

感谢论坛成员的有用提示,我可以展示我的最终解决方案:

main1.adb:

with dongo_h; use dongo_h;
with Interfaces.C; use Interfaces.C;
with Interfaces.C.Strings; use Interfaces.C.Strings;
with System;

procedure main1 is
    type RFC_CONNECTION_PARAMETER_ARRAY is array (Interfaces.C.int range <>) of RFC_CONNECTION_PARAMETER;
    pragma Convention (C, RFC_CONNECTION_PARAMETER_ARRAY);
    par :    RFC_CONNECTION_PARAMETER_ARRAY(1..2);

begin
    par(1).name     := New_String("ABC");
    par(1).value    := New_String("123");   
    par(2).name     := New_String("ABC");
    par(2).value    := New_String("456"); 
    open(par'address,2);
end;

1 个答案:

答案 0 :(得分:1)

你帖子的评论是正确的,你需要有一个记录数组,并将指针传递给导入的函数。

with Interfaces.C.Strings; use Interfaces.C.Strings;
procedure Main is
  function NS renames New_String;
  type Record_Parameter is record
    Name  : Chars_Ptr;
    Value : Chars_Ptr;
  end record;
  type Array_Record_Parameter 
    is array (Int range <>) of Record_Parameter;
  type Access_Array_Record_Parameter
    is access all Array_Record_Parameter;
  pragma Convention(C, Access_Array_Record_Parameter);
  procedure Open_With(
    Parameters : in Access_Array_Record_Parameter;
    Count      : in Int);
  pragma Import(Stdcall, "open", Open_With);
  Parameters : aliased Array_Record_Parameter :=
    ((NS("ABC"), NS("123")), (NS("ABC"), NS("456"))); 
  begin
    Open_With(Parameters'access, Int(Parameters'length)); 
  end Main;

编辑:'应该使用访问而不是'Unrestricted_Access,参数应该是'别名'