显式链接到 DLL 中的类

发布于 2024-07-25 08:20:00 字数 2127 浏览 7 评论 0原文

我有一个类当前位于 .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;
}

I have a class that is currently in a .lib file:

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();
        }

};

I can add this lib file to my project and create instances of this class no problem.
My question is, how can i move this to a DLL and dynamically load it, and create instances of this class. What i'm wanting to do is move some common functionality into this dll and share it across multiple projects.

I want to be able to re-compile the dll if needed when changes are made and have the projects use the must recent version; as of now, using a lib, I have to recompile every project after I recompile the dll for the changes to take place, and because the way this system was originally designed, there are 100+ projects that will use this lib/dll and I don't want to recompile 100 different projects each time a change is made.

So, please give me your expert opinions on how i should go about doing this.

I'll be using the dll inside of my projects like so:

    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;

I ended up with something like this:

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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

余生再见 2024-08-01 08:20:00

您可以按照 COM 的方式执行此操作:

  1. 导出 CreateInstance() 函数。
  2. 将 void** 和唯一标识符传递给 CreateInstance()。
  3. 您使用的 DLL 对库 DLL 调用 LoadLibrary() 并调用 CreateInstance()。
  4. CreateInstance() 执行新的 ReportData 并将其返回到 void** 输出参数中。

编辑:

类似:

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

You can do this the way COM does it:

  1. Export a CreateInstance() function.
  2. Pass a void** and unique identifier to CreateInstance().
  3. Your consuming DLL calls LoadLibrary() on the library DLL and calls CreateInstance().
  4. CreateInstance() does the new ReportData and returns it in the void** out param.

Edit:

Something like:

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;
}

Of course, now you have to worry about things like who will free the object, making sure the DLL doesn't get unloaded, etc.

See also DllGetClassObject, DllCanUnloadNow, etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文