Using Data_Make_Struct for incomplete type

Hi all

I am writing a Ruby wrapper for a C library. I can wrap some of the C
structs with Data_Make_Struct but for one of them I get “invalid
application of sizeof to incomplete type”. I expect this has something
to do with that the compiler cannot find a definitive size of the
struct.

Am I on the right track and if so, is there any way around it? Thanks
in advance.

Regards

Erik

Erik L. wrote:

Hi all

I am writing a Ruby wrapper for a C library. I can wrap some of the C
structs with Data_Make_Struct but for one of them I get “invalid
application of sizeof to incomplete type”. I expect this has something
to do with that the compiler cannot find a definitive size of the
struct.

Have you included all the relevant headers?

On 12 Sep, 21:39, Joel VanderWerf [email protected] wrote:


vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Yes, I can do both Data_Wrap_Struct for other structs in the same
library, and create “instances” of the struct in question. The struct
is defined in a lib that I only have as a binary so I cannot
experiment with the source.

I have tried both with Data_Make_Struct and with a construct I found
in a blog post:

struct_name* s = (struct_name*)malloc(sizeof(struct_name));
VALUE obj;
obj = Data_Wrap_Struct(klass, 0, terminate, s);

Both result in the same compile message:

invalid application of sizeof to incomplete type s

The struct contains arrays of pointers to other structs so my guess is
that it has something to do with that the compiler cannot figure out a
definitive size to use for the struct. If that is the case I have no
idea how to work around that.

Thankful for any input.

Regards

Erik

Erik L. wrote:


struct_name* s = (struct_name*)malloc(sizeof(struct_name));
idea how to work around that.
If you don’t at least have the headers[1] it will be hard to do much
with the struct, except pass it back in to the functions of the library.
Maybe that’s enough. In that case, if you can at least determine the
size of the struct, you can define a dummy struct of that size, and that
may work, in a fragile sort of way.

[1] Having the headers is not necessarily the same as having the full
source. I’m assuming that in your case the problem will not be solved by
installing the -dev package of the library?

Erik L. wrote:

I have read up a bit on the problem and it is like I suspected. The
struct contains arrays of undeclared size and naturally the compiler
cannot guess the size. For now I have worked around it bu transferring
the struct data to VALUE instance variable, but that solution is not
as pretty as the option of wrapping the full struct.

One more suggestion (maybe the same as what you just said): since the
struct seems to be variable length, what about wrapping a pointer to the
struct instead of the struct itself? In other words, the struct you wrap
is of this type

typedef struct {
struct SomeOpaqueStruct *s;
} MyStruct;

where SomeOpaqueStruct is from the library. It’s a bit less efficient,
because of two dereferences (ruby object -> MyStruct -> s) and the extra
allocation, but that’s probably relatively small.

The wrapped package is a closed source package so there is no
equivalent to a -dev package available.

I have read up a bit on the problem and it is like I suspected. The
struct contains arrays of undeclared size and naturally the compiler
cannot guess the size. For now I have worked around it bu transferring
the struct data to VALUE instance variable, but that solution is not
as pretty as the option of wrapping the full struct.

On the other hand there are advantages of doing one “import” step at
creation and then have the struct data as Ruby VALUEs, so it is kind
of ok. I will hopefully release an alpha version of the bindings
within a week or so and I’d be happy to link to the source on github
at that time for input on how the incomplete struct might be completed
in a “best practice” way.

Thanks for the input so far.

Regards

Erik

Erik L. wrote:

However there is one problem left. All the stuff above is only
possible within the wrapper C code. Once the library call exits and I
am back in Ruby land, the wrapped struct (SomeOpaqueStruct in your
example) is freed and I get a segmentation fault. I realize this is
because of how the wrapped library works but do you know of any way to
prevent this or how to copy the struct, thereby saving it for the
afterworld?

Ouch. Bad library, bad!

On 13 Sep, 19:13, Joel VanderWerf [email protected] wrote:

is of this type

   vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Hmmm, getting very close now. The idea to wrap SomeOpaqueStruct worked
like a charm. Now I can allocate, initialize and retreive the DATA
through this wrapped construction. So many thanks for that one.

However there is one problem left. All the stuff above is only
possible within the wrapper C code. Once the library call exits and I
am back in Ruby land, the wrapped struct (SomeOpaqueStruct in your
example) is freed and I get a segmentation fault. I realize this is
because of how the wrapped library works but do you know of any way to
prevent this or how to copy the struct, thereby saving it for the
afterworld?

Regards

Erik