Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

XS Modules: Dependencies

by esskar (Deacon)
on Aug 22, 2005 at 15:47 UTC ( [id://485710]=perlquestion: print w/replies, xml ) Need Help??

esskar has asked for the wisdom of the Perl Monks concerning the following question:

Hi.

I'm going to write a couple of XS modules (they will be in the Win32 namespace, but i think that is a general question!). Some of them dependent on others. Example:

package Foo::Bar;
package Foo::Bar::Builder;
package Foo::Bar::Store;
* Foo::Bar::Builder creates an Foo::Bar object.
* Foo::Bar objectes can be stored in a Foo::Bar::Store.

Right now i have the following structure:

Foo/Bar.xs
Foo/Bar/Builder.xs
Foo/Bar/Store.xs
How does Foo::Bar::Builder and Foo::Bar::Store know, that there is a Foo::Bar or better what Foo::Bar is! (Builder has a create function that returns a Foo::Bar object (TYPEMAP Foo::Bar T_PTROBJ)).

or is it better to put everything into Foo/Bar.xs like
MODULE = Foo::Bar        PACKAGE = Foo::Bar
MODULE = Foo::Bar        PACKAGE = Foo::BarPtr
MODULE = Foo::Bar::Store        PACKAGE = Foo::Bar::Store
MODULE = Foo::Bar::Store        PACKAGE = Foo::Bar::StorePtr
MODULE = Foo::Bar::Builder        PACKAGE = Foo::Bar::Builder
MODULE = Foo::Bar::Builder        PACKAGE = Foo::Bar::BuilderPtr
or (like that?)

MODULE = Foo::Bar        PACKAGE = Foo::Bar
MODULE = Foo::Bar        PACKAGE = Foo::BarPtr
MODULE = Foo::Bar        PACKAGE = Foo::Bar::Store
MODULE = Foo::Bar        PACKAGE = Foo::Bar::StorePtr
MODULE = Foo::Bar        PACKAGE = Foo::Bar::Builder
MODULE = Foo::Bar        PACKAGE = Foo::Bar::BuilderPtr

<edit1>Typo fixed.</edit1>
<edit2>So in general, how do i call the new function of Foo::Bar (defined in Foo/Bar.xs) inside Foo/Bar/Builder.xs?</edit2>

Replies are listed 'Best First'.
Re: XS Modules: Dependencies
by diotalevi (Canon) on Aug 22, 2005 at 17:41 UTC

    Hey, what gives? It sounds like you haven't sorted out how standard perl modules work. Why the XS then? That's like running before you're even walking! In normal perl, you'd just store 'Foo::Bar' into @Foo::Bar::Builder::ISA and @Foo::Bar::Store::ISA. In face, just put this snippet into your Builder.pm and Store.pm.

    One thing you want to be very careful about is to implement as much as possible in plain perl code. Perl data is often highly magical when viewed from the backend and isn't straightforward at all. Your reasons for writing XS should be to interface with other C stuff that isn't accessible from perl or if a selected function has been found to be too slow by profiling. Generally, anything less conservative than that is gunning for trouble.

    package Foo::Bar::Builder; # Same for ::Store use vars qw( @ISA ); @ISA = 'Foo::Bar'; 1
      Yes, i know that. But XS is actually needed since i want to write a OO interface to a (non trivial) Win32 C API.
      (and for sure, i know how to walk! :) )
      so for now i have the following code

      Foo-Bar/typemap
      TYPEMAP PBar T_PTROBJ
      Foo-Bar/Bar.xs
      typedef struct __Bar { // ... } Bar, *PBar; MODULE = Foo::Bar PACKAGE = Foo::Bar PBar new(class); const char* class PREINIT: PBar retval; CODE: New(0, retval, 1, Bar); RETVAL = retval; OUTPUT: RETVAL
      Foo-Bar-Builder/typemap
      TYPEMAP PBarBuilder T_PTROBJ PBar T_PTROBJ
      Foo-Bar-Builder/Builder.xs
      typedef struct __BarBuilder { // ... } BarBuilder, *PBarBuilder; MODULE = Foo::Bar::Builder PACKAGE = Foo::Bar::Builder PBarBuilder new(class); const char* class PREINIT: PBarBuilder retval; CODE: New(0, retval, 1, BarBuilder); RETVAL = retval; OUTPUT: RETVAL MODULE = Foo::Bar::Builder PACKAGE = Foo::Bar::BuilderPtr PBar create(void); PREINIT: PBar retval; CODE: RETVAL = retval; OUTPUT: RETVAL

      so, the question is: do i have to call Foo::Bar::new inside Foo::Bar::Builder::create? or do i have to reimplement the new function of Foo::Bar::new inside Foo::Bar::Builder, or what?
      so, the Foo::Bar::new is now defined inside the Foo/Bar/Bar.dll, and the C compiler does not know, where to find it. I guess it does not help to link against Foo\Bar\Bar.lib, since the dll just exports
      1    0 00001000 _boot_Foo__Bar
      2    1 00001000 boot_Foo__Bar
      
      Get the point?

        It looks like you're doing too much in XS and not enough in perl. Why can't you have your C-allocating routines just return a numified pointer and let perl do all of its own OO stuff? I also feel like I'm getting lost somewhere in your confused code. I'd really like to point you at Simon Cozen's Embedding and Extending Perl book. Or Damian Conway's Object Oriented Perl.

        sub new { my ( $class ) = @_; my $c_ptr = Foo::Bar::_new_or_whatever(); return bless \ $c_ptr, $class; }
Re: XS Modules: Dependencies
by chromatic (Archbishop) on Aug 22, 2005 at 17:32 UTC
    How does Foo::Bar::Builder and Foo::Bar::Store know, that there is a Foo::Bar or better what Foo::Bar is!

    The .pm files that use XSLoader or Dynaloader or whatever you use to load and initialize the shared library of XSUBs can use the other modules.

    ... how do i call the new function of Foo::Bar (defined in Foo/Bar.xs) inside Foo/Bar/Builder.xs?

    Assuming you've already loaded the other shared libraries in your .pm file, they look just like normal Perl subroutines, so call them as normal.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://485710]
Approved by ww
Front-paged by phaylon
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (8)
As of 2024-04-23 12:42 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found