2010-11-30 5 views
1

私たちはDLLを持っていると仮定し、その中にグローバルに格納された配列をエクスポートする必要があります。ファイルからいくつかのコンテンツを読み込んで初期化したいので、個人的に私は自分自身を見つけることができません使用されるようになるだろうどこDLLの配列を初期化するためにこのデザインに何か問題がありますか?

struct Construction{ 
public: 
    Construction(){ 
    //do the initialization thing and read the needed data from the file 
    } 
    SomeType sTArray[100]; 
}; 

__declspec(dllexport) Construction obj(); 

さて、プログラマはそれへの参照を初期化し、その後、以下のような参照を使用することができます:

SomeType (&arrayRef)[100]=obj.sTArray; 
コンストラクタを使用して初期化することができるように構造体に入れるより

あなたはどんな文脈で間違っていると思いますか?

答えて

4

はい、あなたはいくつかの点で非常に厄介な驚きのために自分自身を設定しました。

  1. グローバルオブジェクトコンストラクタは、DLLのCランタイムの起動時に実行されます。
  2. CランタイムスタートアップコードはDLLMainの間に実行されます。
  3. DLLMainの間、DLLローダーロックを保持しています。
  4. オブジェクトコンストラクタは、他のシステムDLLをロードするWin32 APIへの呼び出しを伴う場合があります。
  5. 既にDLLローダーロックを保持している間に別のDLLを読み込むと、処理が急激に終了します。

私は、あなたがそれにアクセスする最初の試みまで、配列を初期化するにはオフに保持することをお勧めしたいあなたは、関数呼び出しの結果として間接的に配列を公開することを必要となる。

struct Construction{ 
public: 
    Construction() : bInit(false) {}; 
    SomeType* GetArray() 
    { 
    if(!bInit) 
    { 
     //do the initialization thing and read the needed data from the file 
     bInit = true; 
    } 
    return sTArray; 
    }; 
private: 
    SomeType sTArray[100]; 
    bool bInit; 
}; 

__declspec(dllexport) Construction obj(); 

もちろん、これは別々のヘッダーファイルと実装ファイルに分割する必要があります。

+1

+1。ルールは "DLLMainで何も複雑にしないでください"です。ファイルからの読み込みは、確かに複雑なものとみなされます。また、DLLMainでファイルを読み込もうとすると、そのファイルが存在しない場合にエラーを処理する良い方法はありません。 – user9876

3

DLL内と実行可能ファイル内のCRTが異なる可能性があるので、割り当てられたオブジェクトを削除するreleaseメソッドでConstructionを指定する必要があります。このようにして、割り当て解除関数が適切なCRTから呼び出されることを保証します。また、コピー操作を除外するポインタでConstructionを返す必要があります。次のコードは、それがどのように実装できるかの方法を示しています

// DLL export header 
struct IConstruction { 
protected: 
    virtual ~IConstruction() {} 
public: 
    virtual void release() =0; 
    virtual SomeType& get_array() =0; 
}; 

__declspec(dllexport) IConstruction* obj(); 

-

// DLL implementation 
struct Construction : public IConstruction { 
    SomeType sTArray[100]; 

    Construction() { /* do initialization */ } 
    virtual void release() { delete this; } 
    virtual SomeType& get_array() { return sTArray; } 
    virtual ~Construction() { /* do clean up */ }  
}; 

IConstruction* obj() { return new Construction; } 
+0

+1:良いアドバイス –

+0

OMGコンパイルしましたか?それはコンパイルされません – Pooria

+0

@ Pooria、これはあなただけでなく、完全な例をcompilableではありません。このコードは、このテクニックを説明するためのものです。たとえば、あなたのコードで 'SomeType'がどのように宣言されたのか分かりません。 –

関連する問題