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.


In reply to Re: Passing NULL pointer through XS without "Use of uninitialized value in subroutine entry" by ikegami
in thread Passing NULL pointer through XS without "Use of uninitialized value in subroutine entry" by kscaldef

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.