http://qs1969.pair.com?node_id=11148270


in reply to Perl XS binding to a struct with an array of chars*

Hi MaxPerl,

It looks to me that:
typedef Edje_Message_String_Set EdjeMessageStringSet; should instead be: typedef struct _Edje_Message_String_Set EdjeMessageStringSet;
Also the following looks wrong to me:
message = malloc(sizeof(Edje_Message_String) + count * sizeof(char *)) +;
The variable "message" is a pointer to a EdjeMessageStringSet type, and memory should be assigned to it as:
message = malloc(sizeof(EdjeMessageStringSet)); or New(0, message, 1, EdjeMessageStringSet); or (in modern perl) Newx(message, 1, EdjeMessageStringSet);
I recommend working your way through the various issues using Inline::C.
It's not a quick fix but, as you become familiar with it, it enables you to test out various options.
It also enables you to post a demo script of problems you are facing. Others can then run that demo to reproduce (and hopefully assist with) the issue.

Here's a little Inline::C demonstrating some basics:
# struct.pl # use strict; use warnings; use Inline C => Config => BUILD_NOISY => 1, CLEAN_AFTER_BUILD => 0, USING => 'ParseRegExp', ; use Inline C => <<'EOC'; struct _Edje_Message_String_Set { int count; char *str[1]; }; typedef struct _Edje_Message_String_Set EdjeMessageStringSet; void struct_size(void) { printf("Size of _Edje_Message_String_Set struct: %d\n", sizeof(EdjeMessageStringSet) ); } EdjeMessageStringSet * _new(char * class, int count, AV * val_arr) { /* Can't be accessed directly from perl unless a typemap is provided */ EdjeMessageStringSet *message; int index; char *string; STRLEN len; Newx(message, 1, EdjeMessageStringSet); if(message == NULL) croak("Failed to allocate memory in _new function"); /* do other stuff ... */ printf("returning EdjeMessageStringSet* from _new\n"); return message; } void DESTROY(EdjeMessageStringSet * x) { /* Can't be accessed directly from perl unless a typemap is provided. Must currently be explicitly called as the EdjeMessageStringSet* object is currently "unblessed". */ Safefree(x); printf("destroyed _new EdjeMessageStringSet*\n"); } void foo(char * pv, int in, AV * arref) { EdjeMessageStringSet *m; m = _new(pv, in, arref); DESTROY(m); } EOC struct_size(); foo("hello world", 2, [1, 2]);
After the script has been compiled, it outputs (for me):
Size of _Edje_Message_String_Set struct: 16 returning EdjeMessageStringSet* from _new destroyed _new EdjeMessageStringSet*
If you look in the ./_Inline/build/ directory you'll find a folder that contains (amongst other things) the XS file that Inline::C automatically generated and used.

Cheers,
Rob