in reply to Passing NULL pointer through XS without "Use of uninitialized value in subroutine entry"
First, keep in mind I've never used XS. I can't guarantee the following works or even its soundness.
If you check the system typemap (lib/ExtUtils/typemap), you'll see the definition of T_PTROBJ. (What is T_OBJECT?) We can create a new rule based on T_PTROBJ to suit our needs.
# typedef struct bar* Bar; # typedef struct type_foo* Foo; TYPEMAP ####### Bar T_NULLABLE_PTROBJ Foo T_NULLABLE_PTROBJ INPUT ##### T_NULLABLE_PTROBJ if ( !SvOK( $arg ) ) { /* if not defined */ $var = NULL; } else if ( sv_derived_from( $arg, \"${ntype}\" ) ) { IV tmp = SvIV( (SV*)SvRV( $arg ) ); $var = INT2PTR( $type, tmp ); } else { Perl_croak( aTHX_ \"$var is not of type ${ntype}\" ) } OUTPUT ###### T_NULLABLE_PTROBJ if ( $var ) /* if defined */ sv_setref_pv( $arg, \"${ntype}\", (void*)$var ); else $arg = &PL_sv_undef;
The usage would be
my $foo = undef; my $bar = Foo::create_bar( $foo );
Update: I don't think addressing the problem in the typemap is the best method. This makes pointers of that type always nullable, whereas that should be decided on a per-function (and even per-argument) basis. That means we should addresses the issue in the XS stub.
# typedef struct bar* Bar; # typedef struct type_foo* Foo; # In typemap: # Bar T_PTROBJ # Foo T_PTROBJ struct bar* create_bar(foo_sv = 0) SV* foo_sv CODE: struct type_foo* foo = NULL; if ( !foo_sv ) { /* Use default of NULL. */ } else if ( !SvOK( foo_sv ) ) { /* Use default of NULL. */ } else if ( sv_derived_from( foo_sv, 'type_foo' ) ) { IV tmp = SvIV( (SV*)SvRV( foo_sv ) ); foo = INT2PTR( struct type_foo*, tmp ); } else { Perl_croak( aTHX_ "\$foo is not of type foo_type" ) } RETVAL = my_c_create_bar(foo); OUTPUT: RETVAL
Bonus: The = 0 and the if ( !foo_sv ) allows the parameter to be omitted. Feel free to remove this.
Update: Now uses tabs in typemap, as required.
Update: struct bar* and struct type_foo* are no good for type T_PTROBJ — search for T_PTROBJ_SPECIAL in perlxs — so I added typedefs.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Passing NULL pointer through XS without "Use of uninitialized value in subroutine entry"
by kscaldef (Pilgrim) on Aug 22, 2006 at 23:30 UTC | |
by ikegami (Patriarch) on Aug 22, 2006 at 23:33 UTC | |
by kscaldef (Pilgrim) on Aug 23, 2006 at 17:15 UTC | |
by ikegami (Patriarch) on Aug 23, 2006 at 18:06 UTC |