Re: mingw DLL problem

al davis <[email protected]>
Newsgroups gmane.comp.gnu.gnucap.devel,gmane.comp.cad.geda.devel
Message-ID <[email protected]>
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..

al@floyd:/tmp/al/2>./a.out ./my_dll.so 
89
al@floyd:/tmp/al/2>./a.out ./my_other_dll.so
130
al@floyd:/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????????????
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.