显式链接到DLL中的类

时间:2009-06-22 14:11:03

标签: c++ borland-c++

我有一个当前位于.lib文件中的类:

class __declspec(dllexport) ReportData {
public:
        list<FileData *> ReportFileData;
        list<SupressionData *> ReportSupressionData;

        static char *ClientName;
        static char *DataRecieved;

        std::string GenFileConfTemplate();

        ~ReportData()
        {
                ReportFileData.clear();
                ReportSupressionData.clear();
        }

};

我可以将这个lib文件添加到我的项目中并创建此类的实例没问题。 我的问题是,如何将其移动到DLL并动态加载它,并创建此类的实例。我想要做的是将一些常用功能移入这个dll并在多个项目中共享它。

我希望能够在进行更改时根据需要重新编译dll并让项目使用必须最近的版本;截至目前,使用lib,我必须重新编译每个项目后重新编译dll以进行更改,并且因为这个系统最初设计的方式,有100多个项目将使用这个lib / dll和我每次进行更改时都不想重新编译100个不同的项目。

所以,请告诉我你应该怎么做的专家意见。

我将在我的项目中使用dll,如下所示:

    ReportData *rd = new ReportData();

    ReportData::ClientName = "test";

    rd->ReportFileData.push_back(new  FileData("testing", 10, 1));
    rd->ReportFileData.push_back(new  FileData("testing 2", 20, 1));

    std::cout << rd->GenFileConfTemplate();

    delete rd;

我最终得到了类似的东西:

typedef Foo* (__stdcall *CreateFunc)();

int main()
{
        HMODULE dll (LoadLibrary ("..\\LLFileConfirmDLL\\LLFileConfirmDLL.dll"));
        if (!dll) {
                cerr << "LoadLibrary: Failed!" << endl;
                std::cin.get();
                return 1;
        }

        CreateFunc create (reinterpret_cast<CreateFunc>(GetProcAddress (dll, "create")));
        if (!create) {
                cerr << "GetProcAddress: Failed!" << endl;
                std::cin.get();
                return 1;
        }

        Foo *f = create();
        cerr << f->Test();


        FreeLibrary (dll);

        std::cin.get();

        return 0;
}

struct FOOAPI Foo
{
        Foo();
        virtual ~Foo(); 
    virtual int Test();
};

Foo::Foo()
{
}

Foo::~Foo()
{
}

int Foo::Test()
{
        return 5;
}

extern "C" __declspec(dllexport) Foo* __stdcall create()
{
        return new Foo;
}

1 个答案:

答案 0 :(得分:2)

你可以按照COM的方式做到这一点:

  1. 导出CreateInstance()函数。
  2. 将void **和唯一标识符传递给CreateInstance()。
  3. 您正在使用的DLL调用库DLL上的LoadLibrary()并调用CreateInstance()。
  4. CreateInstance()执行新的ReportData并将其返回到void ** out param。
  5. 编辑:

    类似的东西:

    extern "C"
    BOOL CreateObject(REFCLSID rclsid, void** ppv) {
        BOOL success = false;
        *ppv = NULL;
        if (rclsid == CLSID_ReportData) {
            ReportData* report_data = new ReportData();
            if (report_data) {
                *ppv = report_data;
                success = true;
            }
        } else if (...) {
            ... other objects ...
        }
        return success;
    }
    

    当然,现在你必须担心谁将释放对象,确保DLL不会被卸载等等。

    另请参阅DllGetClassObjectDllCanUnloadNow