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 を再コンパイルした後、すべてのプロジェクトを再コンパイルする必要があります。このシステムは元々設計されていたため、この lib/dll を使用する 100 以上のプロジェクトがあり、私は変更が行われるたびに 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;
}
4

1 に答える 1

2

これは、COM と同じ方法で行うことができます。

  1. CreateInstance() 関数をエクスポートします。
  2. void** と一意の識別子を CreateInstance() に渡します。
  3. 使用する DLL は、ライブラリ DLL で LoadLibrary() を呼び出し、CreateInstance() を呼び出します。
  4. CreateInstance() は新しい ReportData を実行し、それを void** out パラメータに返します。

編集:

何かのようなもの:

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なども参照してください。

于 2009-06-22T14:18:11.393 に答える