Discussion:
perl extension statically linked - xsub not called
(too old to reply)
m***@yahoo.com
2008-04-28 05:41:49 UTC
Permalink
Hello,

Perl XS guys please provide some insight n advice ....

I'm developing an app that is embedding perl for some web scarping. I
developed an perl extension that has to callback into my C++ code
while running inside embedded interpreter. If I dynamically link the
perl extension as a .dll then the xsub in the perl extension gets
called correctly and does what I need it to do.

However, if I statically link the perl extension and then link that
with my Visual C++ app with the embedded perl interpreter inside, my
xsub never gets called ?? The linking process completes and there are
no unresolved external symbols. But when my perl code calls the xsub I
get an error message saying 'undefined subroutine' in perl.

The problem is with my static build of my perl extension. I need to
distribute my app and I want to eliminate the dependency on a .dll
perl extension, that is why I am build a static .lib file of my perl
extension. Anybody have any idea about please help. I would greatly
appreciate it.

Thanks.
Best regards to all.

Manoj.
Jan Dubois
2008-04-28 07:49:51 UTC
Permalink
Post by m***@yahoo.com
I'm developing an app that is embedding perl for some web scarping. I
developed an perl extension that has to callback into my C++ code
while running inside embedded interpreter. If I dynamically link the
perl extension as a .dll then the xsub in the perl extension gets
called correctly and does what I need it to do.
However, if I statically link the perl extension and then link that
with my Visual C++ app with the embedded perl interpreter inside, my
xsub never gets called ?? The linking process completes and there are
no unresolved external symbols. But when my perl code calls the xsub I
get an error message saying 'undefined subroutine' in perl.
If you are using the mechanism from win32/Makefile, then you must make sure
you add your extension to the list in STATIC_EXT to make sure it gets
initialized properly. Otherwise you need to add some code to your
xs_init() function to define the bootstrap function in your module via

newXS("MyExt::boot_MyExt", boot_MyExt, __FILE__);

and then make sure you call MyExt::boot_MyExt() manually before calling
any function from MyExt(). The BOOT section in the XS code is responsible
for registering all the XS functions at the Perl level.

Cheers,
-Jan
m***@yahoo.com
2008-04-28 12:00:52 UTC
Permalink
Post by Jan Dubois
If you are using the mechanism from win32/Makefile, then you must make sure
you add your extension to the list in STATIC_EXT to make sure it gets
initialized properly.  Otherwise you need to add some code to your
xs_init() function to define the bootstrap function in your module via
    newXS("MyExt::boot_MyExt", boot_MyExt, __FILE__);
and then make sure you call MyExt::boot_MyExt() manually before calling
any function from MyExt().  The BOOT section in the XS code is responsible
for registering all the XS functions at the Perl level.
Cheers,
-Jan
Hi Jan,

Thank you for the quick reply. I'll try to outline my scenario :-

1) Visual C++ App is called - DataDownloader.exe (with perl 5.8
persistent interpreter inside)

2) getdata.pl is a perl script that is called by the perl interpreter
residing in DataDownloader.exe.

3) DataLoader is the name of the Perl extension that I'm statically
linking (i.e. DataLoader.lib) with my DataDownloader.exe app. This has
a sub named 'DataLoader::Cache' which the getdata.pl calls.

Now in my DataDownloader.exe I have an xs_init() function that does a
newXS("DataLoader::boot_DataLoader", boot_DataLoader, __FILE__);

But my extension still does not get registered 'properly' as my
getdata.pl script cannot see the DataLoader extension routines (i.e.
Cache()) and complains of an 'undefined subroutine'.

Are you saying I should explicitly call boot_DataLoader() in my C++
code ?
If so, then what does the newXS() in xs_init() do ? If I do call
boot_DataLoader() manually, what arguments should I provide it with ?
I looked at the perl headers and dont know what pTHX_ is ?

Please help. My sincere regards.

Manoj.
Jan Dubois
2008-04-28 16:06:10 UTC
Permalink
Post by m***@yahoo.com
Post by Jan Dubois
If you are using the mechanism from win32/Makefile, then you must make sure
you add your extension to the list in STATIC_EXT to make sure it gets
initialized properly.  Otherwise you need to add some code to your
xs_init() function to define the bootstrap function in your module via
    newXS("MyExt::boot_MyExt", boot_MyExt, __FILE__);
and then make sure you call MyExt::boot_MyExt() manually before calling
any function from MyExt().  The BOOT section in the XS code is responsible
for registering all the XS functions at the Perl level.
Thank you for the quick reply. I'll try to outline my scenario :-
1) Visual C++ App is called - DataDownloader.exe (with perl 5.8
persistent interpreter inside)
2) getdata.pl is a perl script that is called by the perl interpreter
residing in DataDownloader.exe.
3) DataLoader is the name of the Perl extension that I'm statically
linking (i.e. DataLoader.lib) with my DataDownloader.exe app. This has
a sub named 'DataLoader::Cache' which the getdata.pl calls.
Now in my DataDownloader.exe I have an xs_init() function that does a
newXS("DataLoader::boot_DataLoader", boot_DataLoader, __FILE__);
But my extension still does not get registered 'properly' as my
getdata.pl script cannot see the DataLoader extension routines (i.e.
Cache()) and complains of an 'undefined subroutine'.
Are you saying I should explicitly call boot_DataLoader() in my C++
code ?
If so, then what does the newXS() in xs_init() do ? If I do call
boot_DataLoader() manually, what arguments should I provide it with ?
I looked at the perl headers and dont know what pTHX_ is ?
You need to pass your own xs_init() as an argument to perl_parse().
That way when the Perl interpreter is initialized you'll already
have the DataLoader::boot_DataLoader() function defined in Perl
space.

Normally this function would be called by DynaLoader::bootstrap(),
but you can't rely on that because DynaLoader will look for your
DataLoader.dll in @INC. Therefore you need to call boot_DataLoader()
explicitly (from Perl code, or via eval_pv()). boot_DataLoader()
will in turn define all the other functions in your XS module
for Perl, so after it returns you should be able to call
DataLoader::Cache().

Cheers,
-Jan
m***@yahoo.com
2008-04-29 07:56:34 UTC
Permalink
Post by Jan Dubois
Post by m***@yahoo.com
Post by Jan Dubois
If you are using the mechanism from win32/Makefile, then you must make sure
you add your extension to the list in STATIC_EXT to make sure it gets
initialized properly.  Otherwise you need to add some code to your
xs_init() function to define the bootstrap function in your module via
    newXS("MyExt::boot_MyExt", boot_MyExt, __FILE__);
and then make sure you call MyExt::boot_MyExt() manually before calling
any function from MyExt().  The BOOT section in the XS code is responsible
for registering all the XS functions at the Perl level.
Thank you for the quick reply. I'll try to outline my scenario :-
1) Visual C++ App is called - DataDownloader.exe (with perl 5.8
persistent interpreter inside)
2) getdata.pl is a perl script that is called by the perl interpreter
residing in DataDownloader.exe.
3) DataLoader is the name of the Perl extension that I'm statically
linking (i.e. DataLoader.lib) with my DataDownloader.exe app. This has
a sub named 'DataLoader::Cache' which the getdata.pl calls.
Now in my DataDownloader.exe I have an xs_init() function that does a
    newXS("DataLoader::boot_DataLoader", boot_DataLoader, __FILE__);
But my extension still does not get registered 'properly' as my
getdata.pl script cannot see the DataLoader extension routines (i.e.
Cache()) and complains of an 'undefined subroutine'.
Are you saying I should explicitly call boot_DataLoader() in my C++
code ?
If so, then what does the newXS() in xs_init() do ?  If I do call
boot_DataLoader() manually, what arguments should I provide it with ?
I looked at the perl headers and dont know what pTHX_ is ?
You need to pass your own xs_init() as an argument to perl_parse().
That way when the Perl interpreter is initialized you'll already
have the DataLoader::boot_DataLoader() function defined in Perl
space.
Normally this function would be called by DynaLoader::bootstrap(),
but you can't rely on that because DynaLoader will look for your
explicitly (from Perl code, or via eval_pv()).  boot_DataLoader()
will in turn define all the other functions in your XS module
for Perl, so after it returns you should be able to call
DataLoader::Cache().
Cheers,
-Jan- Hide quoted text -
- Show quoted text -
Hi Jan,

It worked !
You were right. I had to call boot_Dataloader() in my perl code, I did
not add the 'DataLoader::' to the sub name and it was not working. But
after correcting this mistake, it calling my xsubs. Thank you for all
your help and guidance. Im deeply obliged.

Just out of curiousity, when we invoke newXS(), what does that do for
the bootstrap routine, it just registers it in the global stash but
does not call it ?
But it calls the bootstrap method for dynamic (.dll) extensions ?

If you know, please provide insight.

THANKS !

Manoj.

Loading...