[mercury-users] Constructing Mercury types in C

Peter Ross pro at missioncriticalit.com
Tue Apr 11 09:57:00 AEST 2006


On Mon, Apr 10, 2006 at 03:23:40PM -0500, doug.auclair at logicaltypes.com wrote:
> Dear all,
> 
> Hi!  On occasion I am required to make C call-outs, and
> it would be convenient for me to construct and return
> Mercury typed values from the C code, and then use those
> values in the Mercury code.  Reading the refman, I didn't
> see a way to use a ForeignType that way.
> 
> For example, a transaction's identifier gives a set of
> attributes, some of these attribute values are strings and
> some are integral.  So it'd be nice to construct a
> string.poly_type in the C code and return that for an
> arbitrary input attribute.  Also, it'd be nice to associate
> the attribute's name with its value, so constructing and 
> returning a pair(string, string.poly_type) would also be 
> nice.
> 
> I suppose I could have the C function signature be:
> 
> enum string_poly_type_value { INT, STRING, CHAR, FLOAT };
> void value(const char* lookup_name,
>            enum string_poly_type_value* index,
>            int* maybe0, char** maybe1, char* maybe2,
>            float* maybe3);
> 
> to return the string.poly_type value usable by Mercury,
> but I'm wondering if there's a better way to go about
> doing this.
> 

Below is an example of constructing a list in C, and then throwing
the constructed list in an exception.

:- func empty = list(string).
:- pragma export(empty = out, "MOPENSSL_empty").
empty = [].

:- func mycons(string, list(string)) = list(string).
:- pragma export(mycons(in, in) = (out), "MOPENSSL_cons").
mycons(H, T) = [H|T].

:- pred throw_ssl_exception(list(string)::in) is erroneous.
:- pragma export(throw_ssl_exception(in), "MOPENSSL_throw_exception").
throw_ssl_exception(L) :-
    throw(ssl_exception(L)).


:- pragma foreign_code(c, "
void MOPENSSL_throw_error()
{
    long error;
    char string[BUFFER_SIZE];
    MR_String s;
    MR_Word list;

    list = MOPENSSL_empty();

    error = ERR_get_error();
    while (error) {
        ERR_error_string_n(error, string, BUFFER_SIZE);

        s = MR_make_string((char *) ""%s"", string);
        list = MOPENSSL_cons(s, list);

        error = ERR_get_error();
    }

    MOPENSSL_throw_exception(list);

    return;
}
").

--------------------------------------------------------------------------
mercury-users mailing list
post:  mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the users mailing list