Subject:
[ruby-ffi] Re: Representing an opaque struct pointer
From:
Wayne Meissner
Date:
10/17/13 8:26 PM
To:
ruby-ffi@googlegroups.com

Try this:

pptr = FFI::MemoryPointer.new(:pointer)
gme_open_file(path, pptr, 44100)
emu = pptr.read_pointer
gme_start_track(emu, 0)

That would be the equivalent of the following C

Music_Emu** pptr = (Music_Emu **) malloc(sizeof(Music_Emu *));
gme_open_file(path, pptr, 44100);
Music_Emu* emu = *pptr;
free(pptr);
gme_start_track(emu, 0);

which is the same as:

Music_Emu* emu;
gme_open_file(path, &emu, 44100);
gme_start_track(emu, 0);

... just using malloc+free instead of the stack to manage the memory for the pointer to the Music_Emu pointer.



On Friday, 18 October 2013 07:41:15 UTC+11, Misty De Meo wrote:
I realized after the fact that #get_pointer isn't doing what I expected; unfortunately I'm running into a different problem when creating a pointer from it via FFI::Pointer. My program segfaults when calling gme_start_track() immediately afterwards with the pointer from the first example.

gme_open_file(path, FFI::Pointer.new(ptr), 44100)
gme_start_track(ptr, 0)

Where gme_start_track() is defined as:

gme_err_t gme_start_track( Music_Emu*, int index );
attach_function :gme_start_track, [ :pointer, :int ], :gme_err_t

At a glance I'm not sure what's wrong here - it seems equivalent to the C sample I posted earlier.

On Thursday, October 17, 2013 12:14:59 AM UTC-7, Misty De Meo wrote:
To answer my own question...

The opaque pointer is passed just by creating a new FFI::MemoryPointer of type pointer, like so:

ptr = FFI::MemoryPointer.new(:pointer)
gme_open_file(path, ptr.get_pointer(0), 44100)

That said, I'm having a little difficulty wrapping this particular function - I'm sure I'm just passing one of the arguments wrong, but I'm not quite sure what I'm doing wrong.

I have the specific gme_open_file() function wrapped like this:

attach_function :gme_open_file, [ :string, :pointer, :int ], :gme_err_t

And called like above, where `path` is any string. It exits instantly with a failed assert from the gme library, `require(path && out)` - suggesting to me I'm passing one of the first two arguments incorrectly. My test C program (https://gist.github.com/mistydemeo/f6e0c6e716b3e8a57939) using the same function works fine.

On Wednesday, October 16, 2013 8:57:42 PM UTC-7, Misty De Meo wrote:
Apologies if this has been asked before - couldn't find it on the list
archives or the wiki.

A library I'm using has an opaque struct (actually a pointer to a C++
object usable in pure C code), which is used in most of the functions
in the public C API. How should I represent this in ffi?

For example, the definition and a function using it:

typedef struct Music_Emu Music_Emu;

gme_err_t gme_open_file( const char path [], Music_Emu** out, int sample_rate );

Thanks,
Misty

--
 
---
You received this message because you are subscribed to the Google Groups "ruby-ffi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ruby-ffi+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.