|
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. |
|
From: Weiqi G. <wei...@ne...> - 2002-11-15 16:38:47
|
Carlos Garc=EDa del Monte wrote: > > [...] > Searching for some things I found at=20 > http://www.gamecoding.co.uk/tutorials, Error 404 Not found. Is the URL correct? > [...] > it defines a pure=20 > virtual class and a function for creating a instance of the=20 > object which returns a pointer to it and is declared as=20 > extern "C". This sounds like the approach of COM. The first chapter of Don Box's Essential COM is devoted to explaining this approach. In COM terms, the "public" class an interface, and the "private" class is the implementation. > [...] >=20 > I see the idea, but it works? I didn't see it very clear. Yes it does. I was asking the same questions 8 years ago, and had the good fortune of having my questions answered by Charles Kindel, the COM Guy at Microsoft. http://groups.google.com/groups?hl=3Den&lr=3D&ie=3DUTF-8&oe=3Dutf-8&threa= dm=3D01bb 93ce%248f66b6c0%243016369d%40ckindel-610&rnum=3D3&prev=3D/groups%3Fq%3DCh= arl ie%2BKindel%2BWeiqi%2BGao%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3Dutf-8%26 selm%3D01bb93ce%25248f66b6c0%25243016369d%2540ckindel-610%26rnum%3D3 Google Groups: View Thread "C or C++ for OLE interface implementation." (If the above long URL is broken in transit, try this http://tinyurl.com/2q8g). > My thought was that it avoids the problem when calling the=20 > creating function of the dll, but at the end you will have to=20 > use the member functions, and those will have to be compiled=20 > there by the compiler which built the dll, haven't them the=20 > mangling which generates the problems? Not with pure virtual functions. All compilers, gcc included now, compile // I is the interface with pure virtual functions // I *p =3D give_me_an_I(); p->first_function(); p->second_function(); p->third_function(); into something similar to what is generated by ((p->vtbl) + 0)(); ((p->vtbl) + 1)(); ((p->vtbl) + 2)(); where vtbl is the virtual function table pointer of the implementation class. In other words, pure virtual functions calls compiles into pointer manipulations rather than name look ups. And all compilers do the pointer manipulation the same way, even though they do the name mangling differently. > [...] > So my supposition=20 > about code mangling of the class functions are erroneous,=20 > what happens is that code mangling matters only for exported=20 > functions, not for the other which are yet inside the dll.=20 > And that's the reason why it works. This is not correct. See above. And read Charlie Kindel's response. The reason is *pure virtual* functions and the way they are compiled by *all* the popular Windows compilers. -- Weiqi Gao wei...@ne... |
|
From: Per W. <pw...@ia...> - 2002-11-15 23:27:01
|
Different compilers aren't forced to use the same location of the virtual table pointer, and same order of the entries of the table. Also, some compilers encodes extra information into the virtual table, such as object size etc. I haven't worked anything with COM, but I would assume that you have to use specific compiler flags or pragmas or extra attributes to tell the compiler that it must a normalzied way of declaring the virtual method table. /Per W On Fri, 15 Nov 2002, Weiqi Gao wrote: > Carlos Garc=EDa del Monte wrote: > > > > [...] > > Searching for some things I found at=20 > > http://www.gamecoding.co.uk/tutorials, >=20 > Error 404 Not found. Is the URL correct? >=20 > > [...] > > it defines a pure=20 > > virtual class and a function for creating a instance of the=20 > > object which returns a pointer to it and is declared as=20 > > extern "C". >=20 > This sounds like the approach of COM. The first chapter of Don Box's > Essential COM is devoted to explaining this approach. In COM terms, the > "public" class an interface, and the "private" class is the > implementation. >=20 > > [...] > >=20 > > I see the idea, but it works? I didn't see it very clear. >=20 > Yes it does. I was asking the same questions 8 years ago, and had the > good fortune of having my questions answered by Charles Kindel, the COM > Guy at Microsoft. >=20 > http://groups.google.com/groups?hl=3Den&lr=3D&ie=3DUTF-8&oe=3Dutf-8&threa= dm=3D01bb > 93ce%248f66b6c0%243016369d%40ckindel-610&rnum=3D3&prev=3D/groups%3Fq%3DCh= arl > ie%2BKindel%2BWeiqi%2BGao%26hl%3Den%26lr%3D%26ie%3DUTF-8%26oe%3Dutf-8%26 > selm%3D01bb93ce%25248f66b6c0%25243016369d%2540ckindel-610%26rnum%3D3 > Google Groups: View Thread "C or C++ for OLE interface implementation." >=20 > (If the above long URL is broken in transit, try this > http://tinyurl.com/2q8g). >=20 > > My thought was that it avoids the problem when calling the=20 > > creating function of the dll, but at the end you will have to=20 > > use the member functions, and those will have to be compiled=20 > > there by the compiler which built the dll, haven't them the=20 > > mangling which generates the problems? >=20 > Not with pure virtual functions. All compilers, gcc included now, > compile > // I is the interface with pure virtual functions > // I *p =3D give_me_an_I(); > p->first_function(); > p->second_function(); > p->third_function(); >=20 > into something similar to what is generated by > ((p->vtbl) + 0)(); > ((p->vtbl) + 1)(); > ((p->vtbl) + 2)(); >=20 > where vtbl is the virtual function table pointer of the implementation > class. >=20 > In other words, pure virtual functions calls compiles into pointer > manipulations rather than name look ups. And all compilers do the > pointer manipulation the same way, even though they do the name mangling > differently. >=20 > > [...] > > So my supposition=20 > > about code mangling of the class functions are erroneous,=20 > > what happens is that code mangling matters only for exported=20 > > functions, not for the other which are yet inside the dll.=20 > > And that's the reason why it works. >=20 > This is not correct. See above. And read Charlie Kindel's response. > The reason is *pure virtual* functions and the way they are compiled by > *all* the popular Windows compilers. >=20 > -- > Weiqi Gao > wei...@ne... >=20 >=20 >=20 > ------------------------------------------------------- > This sf.net email is sponsored by: To learn the basics of securing > your web site with SSL, click here to get a FREE TRIAL of a Thawte > Server Certificate: http://www.gothawte.com/rd524.html > _______________________________________________ > Dev-cpp-users mailing list > Dev...@li... > TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm > https://lists.sourceforge.net/lists/listinfo/dev-cpp-users >=20 |