I tried adding an external C library to Perl, more specifically, ActivePerl on PC. Here are my findings:
The recommended way is using something called xsub
, a utility that has its own language, XS. The process is documented in two long manpages, perlxs
and perlxstut
. It’s long and complicated, involving a makefile generated by a local script, makefile.pl, in turn generated by xsub
. The makefile doesn’t work because the backslashes there aren’t escaped. I tried replacing each backslash that wasn’t at the end of a line by two backslashes, but it didn’t work for some other reason. The conclusion is that MakeMake
is broken on PC, and therefore so is xsub
.
Then there is C::DynaLoad
. It allows calling functions from shared libraries. In its doc the author says that xsub
is much cooler, but doesn’t explain why. The only reason I can think of is that it can work with Perl variables, but then why not allow passing those variables directly to C functions? Anyway, guess what. C::DynaLoad
is written using xsub
. So I still had to build it using the makefile and everything, and the makefile was still broken. I tried to find it compiled for PC, but failed.
Now on PC there is Win32::API
. Actually it allows calling any function from a DLL. It’s like C::DynaLoad
, only it doesn’t require compilation. It actually can receive the C prototype of a function, and you can pass structs that on the Perl side look like hashes. I compiled the library I needed into a DLL, and it works just fine.
On PC, calling C functions in DLLs is standard. This isn’t surprising, since it’s a very simple interface. Why does Linux require jumping through all those hoops? I suppose because it’s more interesting in a geekish way. And that’s symptomatic of the general reason why Linux isn’t popular.
As an aside, I used MinGW
, a port of gcc
, to compile the DLL. You have to make the functions __declspec(dllexport)
and WINAPI
(because that’s what Win32::API
expects). Now gcc
understands the former, but the latter is defined in "winnt.h"
, on which gcc
chokes. It turns out that WINAPI
is defined to mean __stdcall
(not __pascal
any more), and gcc
understands that. Then the function names are decorated with @4
. I suppose it’s possible to turn off this decoration, but it’s simpler to pass the decorated function names to Win32::API
. It works. The flag for making DLLs is -shared
.