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

Reply via email to