I got the crazy idea in my head to try embedding Rotor into Apache, but
I'm not sure if it's possible. My first step was to figure out if I could
create a static library that embeds rotor, and link to it from a simple C
program.
I started out with the ffitest example in sscli/tests/dev/ffitest, and
changed it to compile to a library instead of an executable. So I made
these changes to the sources file, which should leave me with
./rotor_x86/ffi_test.lib:
===================================================================
RCS file: RCS/sources,v
retrieving revision 1.1
diff -r1.1 sources
29,30c29,30
< TARGETNAME=..\..\ffi_test
< TARGETTYPE=PROGRAM
---
> TARGETNAME=ffi_test
> TARGETTYPE=LIBRARY
===================================================================
I noticed that ffitest and clix (both executables that "embed" Rotor) are
linked with several ctr*.o files as well as palcrt1.o:
ld -o /home/bjepson/src/sscli/clr/bin/rotor_x86/fastchecked/clix
/usr/lib/crti.o
/usr/lib/crtbeginS.o
/usr/lib/crtendS.o
/usr/lib/crtn.o
/home/bjepson/src/sscli/pal/unix/startup/objdf/palcrt1.o
[... stuff deleted ...]
objdf/rotor_x86/clix.obj
So, I got to wondering whether I could build link against ffitest.lib
without palcrt1.o and ctr*.o, since I think (but I'm not positive) that
these will give me trouble if I try to build a shared library that embeds
Rotor (this is needed for creating an Apache module).
I noticed that sscli/pal/unix/startup/palcrt1.c invokes PAL_Initialize and
PAL_Terminate, so I added that to ffitest.cpp. I also added an extern "C"
wrapper to what used to be the main() method (now invoke_random) so I
could call it from a C program (otherwise C++ name mangling would trip me
up). Here are the changes I made:
===================================================================
RCS file: RCS/ffitest.cpp,v
retrieving revision 1.1
diff -r1.1 ffitest.cpp
28c28,30
< int __cdecl main(int argc, char ** argv, char ** envp)
---
> extern "C" {
>
> int invoke_random(int argc, char ** argv, char ** envp)
33a36,40
> if (PAL_Initialize(argc, argv))
> {
> exit(1);
> }
>
65a73
> PAL_Terminate();
67a76,77
> }
>
===================================================================
Now, here's my C program that calls invoke_random:
===================================================================
#include <stdio.h>
int main(int argc, char ** argv, char ** envp)
{
int rc = invoke_random(argc, argv);
return rc;
}
===================================================================
and here is the Makefile, where I turn ffi_test.lib into a .a library and
then compile and link embed.c (I'm not sure if this is the best way to do
this; perhaps I could have linked directly against ffi_test.lib):
===================================================================
LIBS=-L. $(LD_LIB_DIRS) -lembed \
-lrotor_pal -lrotor_palrt -lsscoree
all: embed
rotor_x86/ffi_test.lib: ffitest.cpp
nmake
libembed.a: rotor_x86/ffi_test.lib
ar cq libembed.a rotor_x86/ffi_test.lib
ranlib libembed.a
embed: libembed.a embed.c
gcc embed.c -o embed $(LIBS)
===================================================================
Then, when I run ./embed, I get this:
System.Random.Next() returned 1342023869
Segmentation fault (core dumped)
Now, if I link crt*.o and palcrt1.o in front of embed.c, I don't get the
segfault. If I didn't get the segfault, my next step would be to try
creating a shared library out of ffitest.cpp. Then, I'd like to link to
it without having to put all the ctr*.o and palcrt1.o object files in the
link line.
So, what I'm looking for is a way to host Rotor inside a shared
library. And I want to link against that library without the custom entry
point plumbing that's inside palcrt1.o. Is such a thing possible? I'm
probably just not doing the initialization properly.
Thanks,
Brian