FFI and a struct containing a string and allocating memory space

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

FFI and a struct containing a string and allocating memory space

Brian Sammon-2
If I have a struct like
struct EventInfo {
        char * event_name;
        int year;
        int month;
        int date;
}

and an associated haskell datatype that I want to marshall into it, it seems to me that I can't take advantage of the speed advantages of alloca (and its friends like "with")

The only safe way I've thought of to do this is to do this is to have the poke function for EventInfo (the associated haskell type) call malloc (or newCAString or something) and then poking the string into the newly allocated space.
I realized after a few successful runs of using withCString in the poke function for EventInfo, that I don't think that this (calling withCString from the poke function) was a safe approach, and I'm thinking it was just dumb luck that this worked at all.

Thoughts?  Am I on the right track?  Am I missing any better approaches?

(I'm using Haskell 8.0.1 and a Storable instance for EventInfo, BTW)
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: FFI and a struct containing a string and allocating memory space

Patrick Chilton
You could make your own `withEventInfo :: EventInfo -> (Ptr CEventInfo -> IO a) -> IO a` that calls withCString internally, and gives the passed function a pointer that is valid for the execution of the function. You could also use inline-c and create a struct EventInfo when you need it, and then you know that your bindings are typesafe, which you don't get with Storable etc.

On Tue, Aug 8, 2017 at 7:45 PM, Brian Sammon <[hidden email]> wrote:
If I have a struct like
struct EventInfo {
        char * event_name;
        int year;
        int month;
        int date;
}

and an associated haskell datatype that I want to marshall into it, it seems to me that I can't take advantage of the speed advantages of alloca (and its friends like "with")

The only safe way I've thought of to do this is to do this is to have the poke function for EventInfo (the associated haskell type) call malloc (or newCAString or something) and then poking the string into the newly allocated space.
I realized after a few successful runs of using withCString in the poke function for EventInfo, that I don't think that this (calling withCString from the poke function) was a safe approach, and I'm thinking it was just dumb luck that this worked at all.

Thoughts?  Am I on the right track?  Am I missing any better approaches?

(I'm using Haskell 8.0.1 and a Storable instance for EventInfo, BTW)
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.


_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: FFI and a struct containing a string and allocating memory space

Brian Sammon-2
On Tue, 8 Aug 2017 20:03:16 +0200
Patrick Chilton <[hidden email]> wrote:

> You could make your own `withEventInfo :: EventInfo -> (Ptr CEventInfo ->
> IO a) -> IO a` that calls withCString internally, and gives the passed
> function a pointer that is valid for the execution of the function. You

This seems a little more complicated than the malloc method, so I think I'd save it for if using the malloc method makes my program too slow.

Also, I was thinking of a solution similar to what you suggested, and it seems like it would require having the "poke" for the EventInfo Storable not actually put all the data in the C Struct (or not actually using "poke", but something lower-level, for the more-efficient marshalling system).  I envisioned having the EventInfo poke only poking the int fields, and the withCString that populates the string field living elsewhere.  It seems like this would work, but it seems not quite kosher in some way to have a poke that doesn't marshal the full set of fields.


_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: FFI and a struct containing a string and allocating memory space

Zemyla
Then have a separate struct and datatype for the last three fields,
and make that Storable. Alternatively, look into using ForeignPtrs, so
you can have the finalizer free the memory for the EventInfo.

Another thing you might try instead, if you have control of the code,
is to change EventInfo to

struct EventInfo {
    int year;
    int month;
    int day;
    char event_name[1];
};

and use the variable-sized-struct-array trick whose actual name I don't know.

On Tue, Aug 8, 2017 at 9:19 PM, Brian Sammon
<[hidden email]> wrote:

> On Tue, 8 Aug 2017 20:03:16 +0200
> Patrick Chilton <[hidden email]> wrote:
>
>> You could make your own `withEventInfo :: EventInfo -> (Ptr CEventInfo ->
>> IO a) -> IO a` that calls withCString internally, and gives the passed
>> function a pointer that is valid for the execution of the function. You
>
> This seems a little more complicated than the malloc method, so I think I'd save it for if using the malloc method makes my program too slow.
>
> Also, I was thinking of a solution similar to what you suggested, and it seems like it would require having the "poke" for the EventInfo Storable not actually put all the data in the C Struct (or not actually using "poke", but something lower-level, for the more-efficient marshalling system).  I envisioned having the EventInfo poke only poking the int fields, and the withCString that populates the string field living elsewhere.  It seems like this would work, but it seems not quite kosher in some way to have a poke that doesn't marshal the full set of fields.
>
>
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Loading...