Vra

Die meeste van my C/C++ ontwikkeling behels monolitiese module lêers en absoluut geen klasse hoegenaamd, so gewoonlik wanneer ek nodig het om te maak'n DLL met toeganklik funksies, ek het net hulle uitvoer met behulp van die standaard __declspec(dllexport) richtlijn.Dan toegang tot hulle óf via dinamiese LoadLibrary() of ten stel die tyd met'n kop en lib lêer.

Hoe doen jy dit wanneer jy wil uit te voer'n hele klas (en al wat dit se openbare metodes en eienskappe)?

Is dit moontlik om dinamiese las wat klas by runtime en indien wel, hoe?

Hoe sou jy dit doen met'n kop en lib vir stel om tyd te koppel?

Was dit nuttig?

Oplossing

Wat van die laat-bindende?Soos in die laai dit met LoadLibrary() en GetProcAddress() ?Ek gebruik word om in staat te wees laai die biblioteek aan hardloop tyd en dit sou wonderlik wees as jy kan doen wat hier.

So daar is twee maniere om te laai die DLL.Die eerste is die verwysing na een of meer simbole van die DLL (jou classname, byvoorbeeld), verskaf'n toepaslike invoer .LIB en laat die linker vind alles uit.

Die tweede is om uitdruklik te laai die DLL via LoadLibrary.

Óf benadering werk goed vir C-vlak funksie uitvoer.Jy kan óf laat die linker dit hanteer of bel GetProcAddress as jy opgemerk.

Maar wanneer dit kom om te uitgevoer word klasse, tipies net die eerste benadering is gebruik, d. w. s, implisiet skakel na die DLL.In hierdie geval is die DLL is gelaai op aansoek begin tyd, en die aansoek versuim om te laai as die DLL kan nie gevind word nie.

As jy wil om te skakel na'n klas gedefinieer in'n DLL, en jy wil hê dat die DLL om gelaai word dinamies, iewers na program inisiasie, jy het twee opsies:

  1. Skep voorwerpe van die klas met behulp van'n spesiale fabriek funksie, wat intern sal hê om te gebruik ('n klein bietjie van) assembler te "haak" nuut geskep voorwerpe aan hul toepaslike skyf.Dit word gedoen op run-tyd NA afloop van die DLL gelaai is, natuurlik.'n goeie verduideliking van hierdie benadering kan gevind word hier.

  2. Gebruik'n die vertraging-load DLL.

Alles in ag genome...waarskynlik beter om net te gaan met die implisiete koppel, in welke geval jy beslis wil om te gebruik die preprocessor tegniek hierbo getoon.In werklikheid, as jy die skep van'n nuwe DLL in Visual Studio en kies die "uitvoer simbole" opsie hierdie makro geskep sal word vir jou.

Baie geluk...

Ander wenke

As jy die DLL en die module wat die DLL sal gebruik te bou, het 'n soort van # define wat jy kan gebruik om te onderskei tussen een en die ander, dan kan jy so iets doen in jou klas kop lêer:

#if defined( BUILD_DLL )
    #define IMPORT_EXPORT __declspec(dllexport)
#else
    #define IMPORT_EXPORT __declspec(dllimport)
#endif
class IMPORT_EXPORT MyClass {
    ...
};

Edit: crashmstr my klop om dit

!

Ek gebruik 'n paar makros die kode te merk vir invoer of uitvoer

#ifdef ISDLL
#define DLL __declspec(dllexport)
#endif

#ifdef USEDLL
#define DLL __declspec(dllimport)
#endif

verklaar dan die klas in 'n kop-lêer:

class DLL MyClassToExport { ... }

Toe #define ISDLL in die Library, en USEDLL voor insluitende die kop lêer in die plek waar jy wil om die klas te gebruik.

Ek weet nie of jy mag nodig wees om enigiets anders te doen vir die werk met LoadLibrary

'n eenvoudige werk byvoorbeeld Voeg vir die uitvoer van 'n C ++ klas van 'n DLL:

Die gegewe voorbeeld hieronder gee jou net 'n kort oorsig van hoe dll en exe mekaar (selfverduidelikend) kan kommunikeer, maar dit het meer dinge toe te voeg vir die verandering van 'n produksie-kode.

Full monster voorbeeld is verdeel in twee deel

A. Die skep van 'n DLL biblioteek (MyDLL.dll)

B. Die skep van 'n aansoek wat DLL biblioteek (Aansoek) gebruik.

A. DLL projek lêer (MyDLL.dll):

1. dllHeader.h

#ifdef  MYDLL_EXPORTS 
#define DLLCALL __declspec(dllexport)   /* Should be enabled before compiling 
                                           .dll project for creating .dll*/
#else
#define DLLCALL __declspec(dllimport)  /* Should be enabled in Application side
                                          for using already created .dll*/
#endif

// Interface Class
class ImyMath {
public:
    virtual ~ImyMath() {;}
    virtual int Add(int a, int b) = 0;
    virtual int Subtract(int a, int b) = 0;
};

// Concrete Class
class MyMath: public ImyMath {
public:
    MyMath() {}
    int Add(int a, int b);
    int Subtract(int a, int b);
    int a,b;
};

//  Factory function that will return the new object instance. (Only function
//  should be declared with DLLCALL)
extern "C" /*Important for avoiding Name decoration*/
{
    DLLCALL ImyMath* _cdecl CreateMathObject();
};

// Function Pointer Declaration of CreateMathObject() [Entry Point Function]
typedef ImyMath* (*CREATE_MATH) ();

2. dllSrc.cpp

#include "dllHeader.h"

// Create Object
DLLCALL ImyMath* _cdecl CreateMathObject() {
    return new MyMath();
}

int MyMath::Add(int a, int b) {
    return a+b;
}

int MyMath::Subtract(int a, int b) {
    return a-b;
}

B. Aansoek Projek wat vrag en die reeds geskep DLL-lêer skakel:

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

int main()
{
    HINSTANCE hDLL = LoadLibrary(L"MyDLL.dll"); // L".\Debug\MyDLL.dll"

    if (hDLL == NULL) {
        std::cout << "Failed to load library.\n";
    }
    else {
        CREATE_MATH pEntryFunction = (CREATE_MATH)GetProcAddress(hDLL,"CreateMathObject");
        ImyMath* pMath = pEntryFunction();
        if (pMath) {
            std::cout << "10+10=" << pMath->Add(10, 10) << std::endl;
            std::cout << "50-10=" << pMath->Subtract(50, 10) << std::endl;
        }
        FreeLibrary(hDLL);
    }
    std::cin.get();
    return 0;
}

Onlangs het ek myself presies dieselfde vraag, en opgesom my bevindinge in 'n blog post . Jy kan dit nuttig vind.

Dit dek die uitvoer van C ++ klasse van 'n DLL, asook laai hulle dinamies met LoadLibrary, en bespreek 'n paar van die kwessies rondom dit, soos geheue bestuur, naam mangling en roeping konvensies.

As jy bereid is om 'n vtable in die klas wat jy uitvoer sit, kan jy 'n funksie wat 'n koppelvlak terug te voer en te implementeer die klas in die DLL, dan sit dit in die .def lêer. Jy kan hê om 'n paar verklaring bedrieëry doen, maar dit behoort nie te moeilik wees.

Net soos COM. :)

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top