From: roger AT isp DOT uni-kassel DOT de (=?iso-8859-1?Q?Roger_Ren=E9_Kommer?=) Subject: More DLL issues 10 Mar 1998 09:15:42 -0800 Message-ID: <01bd4b86$82373940$60040d8d.cygnus.gnu-win32@ROGKOMUN> Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit To: Hi, In my spare time I still try to play with DLLs using cygwin. Here some of my experiances: I have improved my script cygshared (I'll append it as file attachment, including a test suite with sample Makefile), now supporting calling constructor and destructor of global classes inside a DLL for b18. It also works with the new b19. Now I'm able to compile some parts of the kde package as shared library. Of course there are still problems with global exported objects using cpp to map it to _imp__label, because in the context of C++ often the label is also be used as member variable/function. It is also not very comfortable to include the mydll_dll.h in the sources. Unfortunately, if you forget to include this in the c files, which uses some of the global dll data, the linker doesn't complain about unresolved symbols. It would helpful, if the original 'label' (instead of _imp__label) doesn't appear in libmydll.a. (I solved this, see below.) A better solutions would be a method like this: gcc -c myc.cc --imports mydll.def which does following: myc.cc is passed to the cpp, and after this, it is passed to a parser/lexer, which looks for imported c/c++ global symbols, defined in the mydll.def and patch the sources regarding global imported data. This would have the advantage, that you haven't to touch the sources (which has always problems, if you want to maintain a port like the KDE package) and you can also provide a .def file, which only exports symbols, which really should visible outside the DLL. I think the solution like MS it does, using extensions __declspec(dll[ex|im]port), etc. doesn't fit to cygnus needings, because it does also needs modifications of sourcecode. I would prefer a standard, which looks like more transparent .so solution. (Just a note: in Qt global defined classes are exported (and used) with the name 'red', 'blue', 'green'. Puh!, C++ and cpp is incompatible by design and I understand the language designers of java that they doesn't integrate a cpp.) There is another problem with gcc: In sources we can often found this construction: /* dummy.c: */ #include FILE *yyin = stdin; int main() { return 0; } Actually, because stdin is defined in stdio.h this way: #define stdin (_impure_ptr->_stdin) the compiler complains: 'initializer element is not constant'. If I compile the stuff with g++ the indirection can be resolve. Is there an option of gcc to compile the .c files with enhanced initialization syntax, but without other C++ features? Or can this problem be solved on another way? In C++ there is another problem: mydll.h: class AClass { public : //... int getsomething() { return 42; } }; class BClass { public : static AClass aclass; //... }; mydll.cc: #include "mydll.h" AClass BClass::aclass; //... myexe.cc: #include "mydll.h" void foo() { BClass bclass; bclass.aclass.getsomething(); } To resolve this, you have to replace bclass.aclass with (*__imp__6BClass$aclass). This cannot be solved by cpp macros, but the sources must be modified. In most cases it helps to wrap the access to this static members in non inlined normal or static member functions. If anybody would try to write an integration of linking DLLs into gcc (in a first step what cygshared does as script) I would try to write the lexer/parser to automatically patch sources regarding importing global data. But probably a better way is to enhance cc1.exe and cc1plus.exe, try to patch code generation after yyparse() the sources, before generating asm output. I've tried to take a look at cc1.exe, but although I generally understand how the compiler works, I was not able to find exact place (somewhere between generating the Parse tree and setting up the rtx structure), where I can do the necessary patches. Either I need advice from a gcc guru, or even such a gcc guru had to do the work. TASKS - Do not export global data directly via label 'label' in libDLL.a. It should not be visible! Only '__imp_label' should be visible outside the DLL. I've wrote a patch to dlltool, with a new option --ie