Almost two years ago I realized that Perl 5 has calling conventions just as Parrot does.
That is, just as every Parrot function that passes two integers and a PMC to function and receives a string back looks the same in terms of the registers used, every Perl 5 function that passes two integers and a blessed scalar looks the same in terms of what's on the stack and where.
The same goes for C.
Any Perl function that passes arguments to a C function passes them the same way. The thunking layer that pulls arguments off of Perl's stack and passes them to the C function is the same for all Perl and C functions with the same signatures. The only difference is the C function to call.
Why write all that code more than once? Why compile all that code more than once? Why make people who may not even have compilers installed compile that code when you could have done it when you built Perl and now they never need to have a compiler installed to use pre-compiled C libraries?
One answer (not a good answer, but an answer) is "Because it's difficult to do."
Difficult is not impossible.
I just released P5NCI to the CPAN today. (That link won't work for a couple of hours after I posted it.) I've mentioned it before. I even added a hack about it to Perl Hacks (so I knew I needed to make it work sufficiently to release soon.)
It's not perfect and it's not complete, but it works. I know -- I spent a couple of hours last night and a couple of hours this afternoon wondering at platform-specific differences until I realized that higher-order C isn't entirely portable.
Yet now it works.
Now I need TPF Summer of Code 2006 student to make it perfect. Do you know anyone?