Adding C code to Perl on PC

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.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: