2016-08-11 3 views
0

私はシングルトン(これはVS2015のプロジェクトにヘッダで使用されているVS2008 DLL/libにある)ブーストini_parser - シングルトンDLLの問題

UtilIniFile &UtilIniFile::GetIniFile() 
{ 
    static UtilIniFile s_IniObject; 
    if (/*check if file has been loaded*/) 
    { 
     s_IniObject.Load(s_IniObject.m_fullfile); 
    } 
    return s_IniObject; 
} 

ロード関数が呼び出されるとiniファイルを持っていますエラー/例外なしで正しく解析されます。例外なく -

//boost::property_tree::ptree m_PropTree; 
boost::property_tree::ini_parser::read_ini(CT2A(filename).m_szBuffer, m_PropTree); 

値は、書き込み機能が存在するが、何の問題もなくptreeでから読み取るptreeで/ファイルへの書き込みはありません、です。

get関数は次のようになります。

template <class TValue> 
bool GetValue(const std::string &section, const std::string &key, TValue &value, const TValue &defaultValue = TValue()) 
{ 
    try 
    { 
     value = m_PropTree.get<TValue>(section + '.' + key, defaultValue); 
    } 
    catch (const boost::property_tree::ptree_error &) 
    { 
     return false; 
    } 
    return true; //All fine 
} 

get関数は、IMO、正しく呼び出されたコード内の他のすべての取得機能など。シングルトンゲッターGetIniFileにデバッグし、その値を検査する場合

std::string str; 
sSingletonDefine.GetValue<std::string>("SECTION", "Key", str, "defValue"); 

、すべてが正常に見える、シングルトンの内部ptreeでは、メンバー上の適切なアドレスを持っています。ファンクションから戻ってテンプレートGetValue<std::string>(...)にデバッグすると、ptreeはm_children = 0x0000000fと表示されます。これは、GetValue関数がDLL内から呼び出されたときには起こらない。 MFCクラスのどこかに、呼び出される関数があります。この関数はDLLに入り、そこでiniファイル/ ptreeから何かをロードします。 VS'15プロジェクトから直接値をロードしようとすると、「奇妙な」振る舞いになります。 ptree.getが呼び出される直前に、GetValueテンプレートでLoad呼び出しを追加、Load関数の内部でptreeでのメンバーはGetValueテンプレートで有効なアドレスとバックアドレスが再び無効でいても

。もちろんそれはその後、this was 0xF.がクラッシュします。 DLLがアンロードされていません。

DLLを使用しないテストプログラムでこの問題を再現することは明らかに不可能です。値が正しくロードされ、プログラムは実行を続けます。

誰もがスミラの問題を経験したことがありますか、またはこの問題の可能な解決方法/修正方法/回避策を知っている人はいますか?

+1

異なるバージョンのVC間でstd :: xxxクラス(テンプレート)を渡すことは、未定義の動作です。 MSは内部レイアウトを変更しました。あなたは 'C'インタフェースしか持たない限り、全く同じコンパイラバージョン(同じMSVCバージョンではない)ですべてのコンポーネントを構築することをお勧めします。 –

+0

@RichardCritten私はプロジェクトを管理していないことを認識しています。それらを使用するためのdll /ヘッダー。ソースにアクセスできますが、これらの古いプロジェクトをすぐにVS'15に変更またはアップグレードする予定はありません。私はこれがここの問題だとは思わない。 – Blacktempel

答えて

1

@Richard Crittenのコメントに加えて、シングルトンとDLLは簡単に一緒にブレンドされません。その周りにたくさんの落とし穴があり、私の推奨はDLLを使ってシングルトンを一緒に使うことを避けることです。 (実際には、シングルトンはほとんどの場合、デザインが悪いと思われますが、これは別の話です)。

このコードをそのまま使用する場合は、あなたのシングルトンインスタンスアプリケーション "イメージ"(EXEまたはDLLのいずれであっても、コンパイルされた各バイナリのMicrosoft用語)は初期化されず、DLLのシングルトンインスタンスのみが初期化されます。

より正確な答えを得るためには、sSingletonDefineの定義を見て、GetIniFile()が定義されている情報を入手しなければなりません。デバッグのために

は、GetIniFile()s_IniObjectのアドレスとGetValues()thisポインタのアドレスを見てください。彼らは同じですか?

+0

そして私はそれが明らかであると確信していました。 '#define sUtilIniFile UtilIniFile :: GetIniFile()'は単純な「ショートカット」です。アドレスは同じですが、正しいインスタンスが2つあります。明らかに奇妙なことですが、DLLからクラスをコピーして、現在のプロジェクトで明らかに他の名前と一緒に使用します。私はまだ原因が分からず、時間は短いと思っています...あなたの時間をありがとう。 – Blacktempel