リンクエラー対処について

解決


かかし  2010-11-19 18:55:03  No: 72063  IP: [192.*.*.*]

VC2005 MFCでダイアログベースのアプリとDLLを
作成しています。

リンクエラー対処についてお教え頂けないでしょうか。

ダイアログベースのアプリをプロジェクトのプロパティで「文字セット:Unicode文字セットを使用する」
実装コード
void CMemReadDlg::OnDestroy()
{
  CDialog::OnDestroy();

  // TODO: ここにメッセージ ハンドラ コードを追加します。
  TCHAR  bufName[][4] = {_T("1"), _T("2"), _T("3"), _T("4")};
  CString  str;
  for(int i = 0; i < 4; i++) {
    str = bufName[i];
    //共有メモリ削除
    ShareMemClose(str);  ←  DLL定義関数
  }
}

DLLをプロジェクトのプロパティで「文字セット:マルチ バイト文字セットを使用する」でビルド。
実装コード
__declspec(dllexport) void ShareMemClose(CString bufName)
{
  //バッファ名変換(CString →  int変換)
  int no = _ttoi(bufName);

  //共有メモリ名のチェック
  if( no <= 0 || 5 <= no ) {
//    AfxMessageBox( "削除するメモリ名が不正" );
    CLogCtrl::WriteLog( "ShareMemClose:削除するメモリ名が不正" );
    return;
  }

  // マッピングを解除
  UnmapViewOfFile( memData[no-1].shareBufP );
  // 共有メモリハンドルをクローズ
  CloseHandle( memData[no-1].m_hMapping );
  // ミューテックスオブジェクトの破棄
  delete memData[no-1].m_pMutex;
}

ダイアログベースのアプリをビルドすると以下のリンクエラーが発生してしまいます。
error LNK2019: 未解決の外部シンボル "__declspec(dllimport) void __cdecl ShareMemClose(class ATL::CStringT<wchar_t,class StrTraitMFC_DLL<wchar_t,class ATL::ChTraitsCRT<wchar_t> > >)" (__imp_?ShareMemClose@@YAXV?$CStringT@_WV?$StrTraitMFC_DLL@_WV?$ChTraitsCRT@_W@ATL@@@@@ATL@@@Z) が関数 "public: void __thiscall CMemReadDlg::OnDestroy(void)" (?OnDestroy@CMemReadDlg@@QAEXXZ) で
参照されました。

但し、DLLのプロジェクトのプロパティで「文字セット:Unicode文字セットを使用する」にするとエラーは出ません。
しかし、DLLは他の複数アプリ(「文字セット:マルチ バイト文字セットを使用する」)からも
呼ばれるので「文字セット:マルチ バイト文字セットを使用する」のままにしておきたのです。
また、ダイアログベースのアプリも「文字セット:Unicode文字セットを使用する」ままにしておきたのです。

宜しくお願いいたします。

編集 削除
仲澤@失業者  2010-11-19 20:22:10  No: 72064  IP: [192.*.*.*]

1.DLLは絶対にMBCSにしておかなければならない場合で、
    EXEを絶対にUnicodeにしたい場合。
       ShareMemClose( CStringA( str));
    のように、一旦MBCSのCStringに変換して引数とします。

また、本件と直接は関係ありませんが
void ShareMemClose(CString bufName)
のように、クラスを渡すのは効率が悪いので、必ず
void ShareMemClose(const CString& bufName)
のように設計しましょう。

編集 削除
かかし  2010-11-19 21:24:00  No: 72065  IP: [192.*.*.*]

お世話になっております。

仲澤@失業者さん
御回答頂きまして有難う御座います。
早々に試してみます。

編集 削除
かかし  2010-11-22 10:57:59  No: 72066  IP: [192.*.*.*]

お世話になります。

ShareMemClose(str);
から
ShareMemClose( CStringA( str));
に変更したところ以下のコンパイルエラーが出てしまいました。

c:\memread\memread\memreaddlg.cpp(197) : error C2664: 'ShareMemClose' : 1 番目の引数を 'ATL::CStringT<BaseType,StringTraits>' から 'CString' に変換できません。(新しい機能 ; ヘルプを参照)
1>        with
1>        [
1>            BaseType=char,
1>            StringTraits=StrTraitMFC_DLL<char>
1>        ]
1>        この変換を実行可能なユーザー定義変換演算子がないか、または演算子を呼び出せません。

編集 削除
かかし  2010-11-22 18:00:15  No: 72067  IP: [192.*.*.*]

有難う御座いました。

解決できました。

編集 削除