gnucap-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gnucap-devel] mingw DLL problem


From: al davis
Subject: Re: [Gnucap-devel] mingw DLL problem
Date: Sat, 3 Nov 2007 15:46:47 -0400
User-agent: KMail/1.9.7

On Saturday 03 November 2007, al davis wrote:
> I still can't figure out how to make it work.

I did not explain the problem clearly.  Let me try again...

Here's some files:
::::::::::::::
interface.h
::::::::::::::
struct THING {
virtual int stuff() = 0;
};
extern THING* x;

extern int bar();
::::::::::::::
main.cc
::::::::::::::
#include <iostream>
#include "interface.h"

#if defined(__MINGW32__)
  #include <windows.h>
  #define dlopen(a,b) LoadLibrary(a)
#else
  #include <dlfcn.h>
#endif

THING* x;

int bar()
{
   return 37;
}

int main(int argc, char* argv[])
{
  dlopen(argv[1], RTLD_LOCAL | RTLD_NOW);
  std::cout << x->stuff() << '\n';
  return 0;
}
::::::::::::::
my_dll.cc
::::::::::::::
#include "interface.h"

struct NOT_A_THING : public THING {
  int stuff() {return bar() + 52;}
  NOT_A_THING() {x = this;}
} y;
::::::::::::::
my_other_dll.cc
::::::::::::::
#include "interface.h"

struct NOT_A_THING : public THING {
  int stuff() {return bar() + 93;}
  NOT_A_THING() {x = this;}
} y;
::::::::::::::
Makefile
::::::::::::::
all: a.out my_dll.so my_other_dll.so

a.out : main.cc interface.h
        g++ -rdynamic -ldl main.cc

my_dll.so : my_dll.cc interface.h
        g++ -fPIC -shared my_dll.cc -o my_dll.so

my_other_dll.so : my_other_dll.cc interface.h
        g++ -fPIC -shared my_other_dll.cc -o my_other_dll.so
:::::::::::::::::::::::::::::::::::::

Then I can compile it (make) ..
Then run it.  The program is "a.out".  The argument is what .so 
(dll) to use..

address@hidden:/tmp/al/2>./a.out ./my_dll.so 
89
address@hidden:/tmp/al/2>./a.out ./my_other_dll.so
130
address@hidden:/tmp/al/2>

Note that:
1. The plugin calls a function bar() that is in main.cc.
2. main.cc knows nothing about particular plugins.
3. The interface is done by the constructor of a static object, 
which sets the global "x" to point to it.
4. This is not production code.  It is simplified to illustrate 
the problem.
5. I have already included the changes to main.cc, I think.


The problem:
Making this work on MS-WIndows.

Let's make another one .....
:::::::
another_one.cc
:::::::::
#include "interface.h"

struct I_DONT_CARE_WHAT_YOU_CALL_THIS : public THING {
  int stuff() {return bar()*2;}
  I_DONT_CARE_WHAT_YOU_CALL_THIS() {x = this;}
} y;
:::::::::::::::::::::::

Now compile it ...
    g++ -fPIC -shared another_one.cc -o another_one.so

Now I can run it:
./a.out ./another_one.so

.... and I didn't change main, or its build procedure, at all.


Let's screw it up again ..  I want to load two of them,,,


::::::::::::::
improved_main.cc
::::::::::::::
#include <iostream>
#include "interface.h"

#if defined(__MINGW32__)
  #include <windows.h>
  #define dlopen(a,b) LoadLibrary(a)
#else
  #include <dlfcn.h>
#endif

THING* x;

int bar()
{
   return 37;
}

int main(int argc, char* argv[])
{
  dlopen(argv[1], RTLD_LOCAL | RTLD_NOW);
  THING *w = x;
  dlopen(argv[2], RTLD_LOCAL | RTLD_NOW);
  std::cout << w->stuff() << ' ' << x->stuff() << '\n';
  return 0;
}
::::::::::::::::::::

Now compile that:
g++ -rdynamic -ldl improved_main.cc -o better

.. and run it with 2 args:
$$$ ./better ./my_dll.so ./my_other_dll.so
89 130

Note that:
1. If I static linked my_dll.so and my_other_dll.so into the 
same executable, it wouldn't work because of name clashes.  Yet 
it works this way because RTLD_LOCAL puts each in its own 
scope.
2. I can do any combination.  I can even do the same one twice!
3. After making the added source files, I didn't change the 
original Makefile.  I compiled them separately.  I suppose each 
one could have its own Makefile, but I cannot change the 
original.


This is easy on *ix.  It does exactly what I want.

MS-Windows????????????





reply via email to

[Prev in Thread] Current Thread [Next in Thread]