httpd-apreq-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Randy Kobes <ra...@theoryx5.uwinnipeg.ca>
Subject Re: [mp2 patch] getting APR to work w/o modperl
Date Mon, 10 May 2004 05:48:22 GMT
On Fri, 7 May 2004, Stas Bekman wrote:
[ ... ]
> We want mod_perl_base to be linked statically to APR.so
> and mod_perl.so (that's what my patch does at the moment,
> but instead it links 3 .o files). So how do we make
> windows compiler find the symbols from the base, when
> building APR:: objects? What we want to tell the compiler
> that is that the symbols are in mod_perl_base.lib, but
> they may be found in mod_perl.so or APR.so. Can we do
> that?
>
> Think of APR.so as an equivalent of mod_perl.so, which
> doesn't require httpd.  So for example APR::Pool may find
> its symbols resoved in mod_perl.so or APR.so depending on
> which is loaded. Do you think we can arrange such a thing?

I think it's possible using function pointers - here's an
example (if nothing else, for the benefit of the archives :)

Suppose one has a function testit(), defined in a.c:

=================================================
// file a.c
#include "a.h"
#include <stdio.h>
void testit(void) {
  printf("Bonjour");
}
================================================
with header
===============================================
// file a.h
void testit(void);
===============================================
Making up a def file a.def to define which
symbols to export:
==============================================
LIBRARY
DESCRIPTION 'The a library'
EXPORTS
        testit
=============================================
one can then from a.c create a shared library a.dll:

cl -c a.c
link -dll -nodefaultlib ... a.obj -def:a.def -out:a.dll

where "..." specifies various system .lib files.

Making copies a.c -> b.c, a.h -> b.h, and a.def -> b.def,
one can then create a b.dll shared library that also
exports the testit() function.

Now create a 3rd dll c.dll that exports another
function printit(), which uses the testit() function.
If this is done as
========================================================
// file c.c
#include <windows.h>
#include "c.h"

typedef void (CALLBACK* DLLTESTIT)(void);

void printit(void) {
  HINSTANCE hDLL;               // Handle to DLL
  DLLTESTIT testit;    // Function pointer

  hDLL = LoadLibrary("a");
  if (hDLL != NULL) {
    testit = (DLLTESTIT)GetProcAddress(hDLL,
                                       "testit");
    if (!testit) {
      // handle the error
      FreeLibrary(hDLL);
    }
    else {
      // call the function
      testit();
    }
  }
  else {
    hDLL = LoadLibrary("b");
    if (hDLL != NULL) {
      testit = (DLLTESTIT)GetProcAddress(hDLL,
                                         "testit");
      if (!testit) {
        // handle the error
        FreeLibrary(hDLL);
      }
      else {
        // call the function
        testit();
      }
    }
  }
}
========================================================
with header
=======================================================
// file c.h
void printit(void);
=======================================================
and associated .def file
======================================================
LIBRARY
DESCRIPTION 'The c library'
EXPORTS
        printit
======================================================
then compiling this as

cl -c c.c
link -dll -nodefaultlib ... c.obj -def:c.def -out:c.dll

will have c.dll exporting printit().

Now consider an application:

====================================================
// file printit.c
#include "c.h"

int main(void) {
  printit();
  return 0;
}
=====================================================

If this is compiled as

cl printit.c c.lib

then an executable printit.exe will be produced. This
executable needs c.dll to be available (for printit), as
well as one of a.dll or b.dll (for testit).

Apart from the gymnastics of the implementation, does this
approach sound worth persuing? I guess one advantage here is
that, for Win32, one has to define just the symbols (as
function pointers), and then try loading either APR.so or
mod_perl.so - one doesn't (I think) have to split
mod_perl.lib up into separate libs, according to whether or
not ap_ symbols appear.

I asked Jan Dubois if there was a simpler approach - he
suggested something just involving manipulating the link
options and what appears in the .def file, but I can't get
it to work by just loading one of the dlls ("a" or "b" in
the above example). I'll look at that more closely, though.

-- 
best regards,
randy

Mime
View raw message