From: fjh AT cs DOT mu DOT OZ DOT AU (Fergus Henderson) Subject: Re: export data from a b18 DLL? (stdout bug?) 29 Jul 1997 00:48:30 -0700 Approved: cygnus DOT gnu-win32 AT cygnus DOT com Distribution: cygnus Message-ID: <199707290621.QAA06589.cygnus.gnu-win32@murlibobo.cs.mu.OZ.AU> References: Original-To: gnu-win32 AT cygnus DOT com Original-Sender: owner-gnu-win32 AT cygnus DOT com Ron Kulper 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 | 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 | "I have always known that the pursuit WWW: | 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".