Mail Archives: cygwin/1997/07/29/00:48:30
Ron Kulper <ron AT websci DOT com> writes:
>Is it possible to export data (as opposed to a function) from a dll?
I believe so, but it requires a bit of fiddling around.
See the mail below from Colin Peters.
>Does this issue have anything to do with the bug described below?
Yes...
>I recieve a SIGSEGV when attempting to set a FILE * = stdout within a dll.
I think the problem is that _impure_ptr is not being initialized
properly. I don't know what the correct solution is.
| From: Colin Peters <colin AT bird DOT fu DOT is DOT saga-u DOT ac DOT jp>
| Subject: RE: exported variables from dll
| Date: Sun, 15 Jun 1997 12:20:57 +0900
|
| Philippe GIACINTI[SMTP:giac AT dalim DOT de] wrote:
| >I wish to define some variables in a dll and use them in another, on Unix I
| >have no problems: the variable is defined global in one .cc and extern in
| >another.
| >If I use the same code in Cygwin32, it seems that each dll have a local copy of
| >this variable ( ie: the addresses are different ).
| >I tried to do this with VisualC++, and it works if I use the directive
| >DllImport instead of extern.
| >
| >( in fact I have this problem in a dll which uses stdout, I found that
| >"_impure_ptr" was correctly initialized in main, but was null in the dll )
| >
| >I'm really new in Cygwin32 and Windows environment, and I think (hope) it comes
| >from my ignorance.
|
| It's a little hard to be sure from the information you have given, but I
| think your problem is related to the way dlltool builds import libraries.
| Basically lets say you have a DLL with a function "Foo" and a variable
| "bar". Your .def file will look something like this:
|
| EXPORTS
| Foo
| bar
|
| First thing you should notice: dlltool cannot tell that one of these is
| a function and the other is a variable. Dlltool builds a import library
| basically consisting of functions which do something like this:
|
| Foo ()
| {
| return __imp_Foo();
| }
|
| bar ()
| {
| return __imp_bar();
| }
|
| __imp_Foo and __imp_bar are symbols in a special table that gets filled
| in with the *real* addresses of the Foo and bar symbols when the DLL that
| contains them is loaded at run time.
|
| So when you call Foo, you are actually calling a thunk function statically
| linked into your own code, which effectively looks up the real address of
| the function you wanted and calls it (all the arguments just pass straight
| through).
|
| But what happens to the variable? Well, if you do something like this in
| your code:
|
| x = bar;
|
| The symbol bar is defined and all that, but it's defined as a pointer to
| the *thunk function*! Thus, every dll or program that uses the bar
| variable will, indeed, have it's own copy, because they all have their
| own thunk. And, of course, that value will have absolutely nothing to
| do with what you wanted to do.
|
| In Visual C++ the __dllimport (or __dllexport, whatever) keyword tells
| the compiler directly that the given variable or function is imported
| from a DLL. The compiler can generate the appropriate code directly
| where any reference is made to the given symbol, whether it is a
| function call or variable reference. Thus, no thunks are necessary
| and variable references are correct. You also don't need a .def file
| or an import library at all.
|
| Gcc, as far as I know, does not have a mechanism for doing this (yet), so
| we have to use dlltool to fool the compiler into putting our function
| calls through a thunk. Unfortunately this messes up variable references.
|
| Here is a workaround that I use with the current system:
|
| In your header file do something like this:
|
| #ifdef DEFINING_DLL
| int bar;
| #else
| extern int* __imp_bar;
| #define bar (*__imp_bar)
| #endif
|
| This way when DEFINING_DLL is set (which you only do in the DLL
| which actually contains the variable) you get the normal int
| variable. In the other code which uses the variable any
| reference to bar becomes an indirect reference through the
| __imp_bar variable created by dlltool.
|
|
| This is a temporary solution of course. What *should* happen (IMHO)
| is that gcc should learn how to do that itself and generate the
| appropriate code for shared libraries (I would have thought they
| would do it for UNIX shared libraries anyway). We could then do
| away with dlltool and .def files altogether. Instead your headers
| might look like this:
|
| #ifdef DEFINING_DLL
| #define DLLSYMBOL __attribute__(__dllexport__);
| #else
| #define DLLSYMBOL __attribute__(__dllimport__);
| #endif
|
| int DLLSYMBOL Foo();
| int DLLSYMBOL bar;
|
| or possibly even this:
|
| __dllexport int Foo();
| __dllexport int bar;
|
| As a special wish list item I would like to be able to do something
| like this in C++:
|
| __dllexport class MyClass
| {
| ...
| };
|
| And have all the member functions (and static variables) of the
| class reside in a dll. This would save me the hassle of generating
| .def files for C++ classes, and the worries about the internals
| of virtual functions and inheritance from the exported class (and
| run time type information too, if supported). If this ever happens
| I will be an extremely happy camper. :)
|
| (By the way, I am not really suggesting syntax here, because I
| might have the attribute thing wrong, but I do think it would
| be nice to make it so that, either with a #define or directly,
| headers using MSVC __dllexport type constructs could be used
| with GCC.)
|
| As I said though, this is not yet the case, so you have to
| resort to the above trickery, which is ugly and dependent on
| the undocumented inner workings of dlltool.
|
| Would someone else on the list like to take up the question about
| _impure_ptr? I pretty much only use Mingw32, which has it's own
| DLL startup code that initializes stdout and so on (and doesn't
| use _impure_ptr), so I'm not in a position to know exactly what
| the problem there is.
|
| Anyway, good luck,
| Colin.
|
| -- Colin Peters - colin AT bird DOT fu DOT is DOT saga-u DOT ac DOT jp
| -- Saga University Dept. of Information Science
| -- http://www.fu.is.saga-u.ac.jp/~colin/index.html
| -- http://www.geocities.com/Tokyo/Towers/6162/
--
Fergus Henderson <fjh AT cs DOT mu DOT oz DOT au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh AT 128 DOT 250 DOT 37 DOT 3 | -- the last words of T. S. Garp.
-
For help on using this list (especially unsubscribing), send a message to
"gnu-win32-request AT cygnus DOT com" with one line of text: "help".
- Raw text -