importadavoid-pointers

Import C function with void* parameter


I want to import a C function in Ada.

There is the C part :

void Register(const void *ctxt)
{
   saved_ctxt = ctxt; // This is a global variable 
}

void Send_Trace(const void *ctxt,
                const char *msg)
{
    if (saved_ctxt == ctxt)
    {
        // Do stuff with msg
    }
}

Now I want to use this function in a Ada program. There is my code :

type T_void is tagged null record;
package C renames Interfaces.C;

procedure Send_Trace_From_C(ctxt : in T_void;
                            msg  : in String)
is
    pragma Convention(C, T_void);

    procedure send_trace (A: out T_void; B : C.Strings.char_ptr);
    pragma import (C, Send_Trace, "Send_Trace");

    Char_ptr : C.Strings.char_ptr := C.Strings.New_String(msg);
begin
    send_trace (ctxt, Char_ptr);
end Send_Trace_From_C;

But I have errors :

pragma "convention" argument must be in same declarative part

warning "send_trace" involves a tagged type which does not correspond to any C type

How can I use a *void in Ada ?


Solution

  • You need to declare the convention when you create the type:

    type Foo is ...
    with Convention => C;
    

    Why did you make T_void a tagged record? The compiler can’t export it to C, because the C side wouldn’t understand it, so don’t. A null record is eligible for convention C (ARM B.1(16)). As the code stands, it’s very likely to be passed to the C by address (ARM B.3(69)), which is what you want.

    The first parameter to send_trace should be in-mode.