Howto make an instance of a class defined in a DLL

Discussion in 'C++' started by Bernd Muent, Aug 24, 2006.

  1. Bernd Muent

    Bernd Muent Guest

    Hi together,
    I made a DLL in the following way (simplified example just to explain
    what is the problem) using devcpp and gcc compiler on Windows XP:
    dll.h:
    #ifndef _DLL_H_
    #define _DLL_H_

    #if BUILDING_DLL
    # define DLLIMPORT __declspec (dllexport)
    #else /* Not BUILDING_DLL */
    # define DLLIMPORT __declspec (dllimport)
    #endif /* Not BUILDING_DLL */

    class DLLIMPORT DllClass
    {
    public:
    DllClass();
    virtual ~DllClass(void);
    void testVoid();
    };
    -------------------------------------------------
    dll.cpp:

    #include "dll.h"
    #include <windows.h>
    #include <iostream>

    DllClass::DllClass() {}
    DllClass::~DllClass () {}
    void DllClass::test() {
    printf("testFunction called!\n");
    }

    BOOL APIENTRY DllMain (HINSTANCE hInst /* Library instance handle. */ ,
    DWORD reason /* Reason this function is
    being called. */ ,
    LPVOID reserved /* Not used. */ ) {
    return true;
    }
    -------------------------------------------------

    So far, so good, I could compile it with gcc and got a dll.dll as output.
    dumpbin /exports dll.dll gives the following output:
    ordinal hint RVA name

    1 0 000011D0 _Z5testFv
    2 1 000011F0 _ZN8DllClass4testEv
    4 2 00001250 _ZN8DllClassC1Ev
    5 3 00001230 _ZN8DllClassC2Ev
    6 4 00001290 _ZN8DllClassD0Ev
    7 5 00001280 _ZN8DllClassD1Ev
    8 6 00001270 _ZN8DllClassD2Ev
    9 7 00041C9C _ZTV8DllClass

    So, the Class and ist included void are exported.
    [Question beside: Why have the symbols such cryptic names. Do I have any
    influence to rename them just to "DllClass" etc.?]

    No I made a host application:
    main.cpp:
    -------------------------------
    #include <cstdlib>
    #include <iostream>
    #include <windows.h>
    #include "dll.h"

    using namespace std;

    int main(int argc, char *argv[]) {
    HMODULE hMod = LoadLibrary("dll.dll");
    if (hMod==NULL) {printf("DLL NOT LOADED\n"); return 1} else printf("DLL
    LOADED\n");

    DllClass *pDllClass = (DllClass *) malloc (sizeof (DllClass));
    if (NULL == pDllClass) {printf ("Memory allocation failed\n");return 1;}
    else printf("Memory allocated\n");

    typedef void (WINAPI * PCTOR) ();
    PCTOR pDLLClass = (PCTOR) GetProcAddress (hMod, "_ZTV8DllClass");
    if (NULL == pDLLClass) {printf ("GetProcAddress failed\n");} else
    printf ("DLL ProcAddress success\n");
    -------------------------------------
    But now? How to make an instance of this class?
    I found this hint:
    https://secure.codeproject.com/dll/classesexportedusingLL.asp
    __asm { MOV ECX, pDLLClass }
    pDLLClass();

    But the assember syntax is for Visual C++, not working with gcc.
    I tried:
    asm("MOV ECX, pDLLClass");
    But this does not compile:
    "too many memory references for `mov'"

    Sorry, I've got no experience in programming assembler on a X86 machine,
    the last time I did assembler programming was on a ZX81 von VC 64 some
    20 years ago ;-)

    Thank you for any tips how to get an instance of a class which is
    defined in a dll, Bernd

    --
    Bernd M√ľnt Durchwahl: 030/69032-509
    euroscript Deutschland GmbH Zentrale: 030/69032-300
    Abteilung IT-Management Fax: 030/69032-505
    Alt-Moabit 91 Mail:
    10559 Berlin Web: http://www.euroscript.de

    --
    BM Computer-Services, Bergmannstr. 66, 10961 Berlin
    Webdesign, Internet, Layout und Grafik
    Tel.: 030/20649400, mobil 0175/7419517, Fax: 030/20649401
    Web: http://www.bmservices.de, eMail:
    Bernd Muent, Aug 24, 2006
    #1
    1. Advertising

  2. Bernd Muent

    benben Guest

    [snip]
    > But now? How to make an instance of this class?

    [snip]

    Your problem will be much better addressed in other dedicated newsgroups
    such as microsoft.public.vc.*

    There are a number of solutions in my mind but bothering assembly is the
    least you should try. So don't do it.

    You can add another function in your DLL that instantiates the class and
    returns a pointer to the instance. Make sure you use extern "C". In the
    client code all you have to do is to call such a factory function to get
    a pointer to an instance.

    You probably need to provide another function for memory reclamation.

    Ben
    benben, Aug 24, 2006
    #2
    1. Advertising

  3. Bernd Muent

    Bernd Muent Guest

    benben schrieb:

    > Your problem will be much better addressed in other dedicated newsgroups
    > such as microsoft.public.vc.*


    No. I wrote that I am using devcpp with gcc on windows. The only example
    I found was for MSVC.

    > There are a number of solutions in my mind but bothering assembly is the
    > least you should try. So don't do it.


    That's my opion too.

    > You can add another function in your DLL that instantiates the class and
    > returns a pointer to the instance. Make sure you use extern "C". In the
    > client code all you have to do is to call such a factory function to get
    > a pointer to an instance.


    Ok, I did it that way:
    dll.h:
    extern "C" DLLIMPORT DllClass* createDllClass();

    dll.cpp:
    DllClass* createDllClass() {
    return new DllClass;
    }

    In the program using the dll:
    typedef DllClass* (*PCreate) ();
    PCreate createDC=(PCreate)::GetProcAddress (hMod,"createDllClass");
    DllClass *pD=createDC();
    if (cD) printf("Pointer\n");

    That's working, I got a pointer to the newly created instance of the class.

    And then further testing:
    printf("var: %d\n",pD->var);

    That's working, too. "var" is declared as an public integer var in the
    class.

    But now:
    pD->test();

    This does compile but the linker complains about an unresolved symbol to
    the void test.
    OK, as far as I understand: the library is loaded at run time and then
    this symbol will be there. But not at link time.
    As far as I know, gcc is not able to create something like a static
    library ".lib" to use at link time.
    What to do?

    I also tried:
    void (FAR __stdcall *(test))()=NULL;
    test = (void (__stdcall *)())GetProcAddress (hMod,"_ZN8DllClass5testEv");
    test();

    But this is obviously not the pointer to the function inside the
    instance. This is something like a pointer to a static member of my test
    class similar to DllClass::test(); And this will not work. If there is
    something like "var+=10;" inside the function test, the program crashes
    becauce there is no memory allocated.


    > You probably need to provide another function for memory reclamation.


    How? Can you give me an example?

    Greetings, Bernd



    --
    BM Computer-Services, Bergmannstr. 66, 10961 Berlin
    Webdesign, Internet, Layout und Grafik
    Tel.: 030/20649400, mobil 0175/7419517, Fax: 030/20649401
    Web: http://www.bmservices.de, eMail:
    Bernd Muent, Aug 25, 2006
    #3
  4. Bernd Muent

    red floyd Guest

    Bernd Muent wrote:
    > benben schrieb:
    >
    >> Your problem will be much better addressed in other dedicated
    >> newsgroups such as microsoft.public.vc.*

    >
    > No. I wrote that I am using devcpp with gcc on windows. The only example
    > I found was for MSVC.
    >


    You're still OT here. Try gnu.g++.help
    red floyd, Aug 25, 2006
    #4
  5. Bernd Muent

    red floyd Guest

    Bernd Muent wrote:
    > benben schrieb:
    >
    >> Your problem will be much better addressed in other dedicated
    >> newsgroups such as microsoft.public.vc.*

    >
    > No. I wrote that I am using devcpp with gcc on windows. The only example
    > I found was for MSVC.
    >


    Your argument is equivalent to:

    "I went to the butcher, looking for fresh apples. They told me to go to
    the fishmonger. The fishmonger didn't have apples, so I came back to
    the butcher."

    Try gnu.g++.help.
    red floyd, Aug 25, 2006
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Anushi
    Replies:
    5
    Views:
    8,625
  2. Sridhar R
    Replies:
    14
    Views:
    1,380
    =?iso-8859-1?Q?Fran=E7ois?= Pinard
    Feb 10, 2004
  3. Oodini
    Replies:
    1
    Views:
    1,749
    Keith Thompson
    Sep 27, 2005
  4. Martin P. Hellwig
    Replies:
    1
    Views:
    362
    Martin P. Hellwig
    Mar 26, 2010
  5. H. Simpson
    Replies:
    4
    Views:
    243
    H. Simpson
    Aug 3, 2004
Loading...

Share This Page