|
From: Carlos d. M. <cg...@wo...> - 2002-11-15 11:39:27
|
Hi: First of all, I haven't ever yet written any dll, so I don't know deeply what can be the true value of this. So I ask your forgiveness if it is a bad pointing. But some days ago here (mingw-users) was a thread of messages about dll, in which I read speaking about the problems of C++ code inside dlls, just due to the function's mangling for support overloading in c++. Searching for some things I found at http://www.gamecoding.co.uk/tutorials, a work about memory management and dlls by Steve Riggal where the author proposes a way for working with objects inside dlls. Since the title of the subsection (it is treated in chapter 4) is portable class exports, I understands he claims with that you can make a dll for use with any compiler/system. In short, his way consists on making two classes, one private to the dll and one public. First the public: it's a header file you'll have to include in your source file (it is done for implicit loading, through a lib file which has an export table, but I guess it should work in explicit loading), it defines a pure virtual class and a function for creating a instance of the object which returns a pointer to it and is declared as extern "C". Nothing more. All its functions are pure virtual, and only define the functions (at least in the example he gives, but I assume it will be done this way always). Then a def file which exports only the function for creating an object. And a private one. It is a derived class from the one dclared in the public header. The header file declares the function and all the members of the class (the same functions), and includes the other header. And its correspondent source file with the implementation of all functions, including the one which creates the objects. The creator says: public_header_class *object_creator_function(){ return new private_header_class; } And for destroy the class: void private_header_class::Destroy(){ delete this; } Then he builds the dll with them. In the cpp of the program (linked to the lib file) he creates instances of the class by: public_header_class *object = object_creator_function(); and then he uses all the functions as usual object->member_function(parameters); I see the idea, but it works? I didn't see it very clear. My thought was that it avoids the problem when calling the creating function of the dll, but at the end you will have to use the member functions, and those will have to be compiled there by the compiler which built the dll, haven't them the mangling which generates the problems? Don't you have your source file being mangled with your compiled ways and the dll with its builder way of mangling? Or it happens only for the function that will be exported, and the others lose the decoration? Wouldn't be better use structs besides all their limitations (I mean if portability is a matter)? So I decided try it building the executable with mingw and Borland5.5, using the dll produced by mingw and the one provided by the author. Then I built both the dll and the executable with MinGW and ran without problems. I've tried to build the user project linking to the lib file he provides with the examples, surely it was compiled with visual C++, I compile it succesfully, but when I run it generated an access violation. And I haven't done anything wrong during compiling, since I did it twice: one with the dll from the example, compiled by the author (surely with Visual C++), in which case it generated the access violations, and another time with the dll generated by mingw, in this case it ran without problems even using the lib provided by the author. I tried then with Borland, and it worked!. It works linking to the dll produced by mingw, so it is true. So my supposition about code mangling of the class functions are erroneous, what happens is that code mangling matters only for exported functions, not for the other which are yet inside the dll. And that's the reason why it works. However linking to the dll provided with the zip file you find in the tutorial, which has all the sources, produces memory access violations. Now I noticed that the dll provided by him is 200Kb, and the one produced by mingw is 29Kb, that makes me think as something almost evident he is providing a debug version of the dll, and that's the reason it doesn't work with executables produced by mingw and borland. The only point with Borland is since I didn't build the dll with Borland, I had to use coff2omf (an app with borland which translates coff format libs to omf) over the import library, and link to it, in that process the effect is that the executable doesn't ask for mydll2.dll, it asks for DS00000.o, so I had to rename it, but I guess it is a problem that can be solved in some way. And if I use the lib provided by the author it says "undefined reference to %s", where %s is the create_public_object_function() preceded by an underscore. The only I left now to do, and I'll see later is what happens about inheritance from it, but I suppose there would be an easy way of work around it if it doesn't work directly. |