こんばんは。
C++をはじめて間もない者です。
_bstr_tの使い方でどツボにはまってしまいましたので、質問させて頂きます。
XMLファイルのアクセスを行うクラスを「.lib」で作成し、
それを使用してXMLファイルへのアクセスを行っていました。
無事に取得出来ることを確認し、この.libの処理を.dllへ移行して使用するようにしたのですが、ここで問題が発生いたしました。
XMLより文字列を取得する関数で引数に_bstr_tを使用しているのですが、
なぜか複数回(2回目以降)呼ぶと以下のようなエラーが発生するようになってしまいました。(debugモードにて確認)
何が原因かがつかめず先に進めなくなってしまいました。
そもそも、_bstr_tの使い方が間違っている可能性もあると思いますが、
よろしくご教授お願いいたします。
-------------------------------------------------------
Debug Assertion Failed!
〜省略〜
File: dbgheap.c
Line: 1011
Expression: _CrtIsValidHeapPointer(pUserData)
-------------------------------------------------------
以下、テスト的に作成したプログラムです。
DLL側:
DWORD CTest::GetBSTR(_bstr_t &bstrVal)
{
bstrVal.operator =("Test");
return 0;
}
呼び出し側:コンソールアプリ
int main(int argc, char* argv[])
{
CTest test;
_bstr_t bstrVal;
for(int i=1; i < 100;i++){
test.GetBSTR(bstrVal);
printf("%d BSTR=[%s]\n",i,(char*)bstrVal);
}
printf("end\n");
return 0;
}
論点がずれているかもしれませんが・・・
DWORD CTest::GetBSTR(_bstr_t &bstrVal)
ではなく
DWORD CTest::GetBSTR(_bstr_t *bstrVal)
にして
test.GetBSTR(bstrVal);
が
test.GetBSTR(&bstrVal);
では?
引数で変数やクラスのアドレスを参照させるならこうですよね?
補足。
質問をするときには、開発環境も記載した方がよいと思います。
VCだと仮定しても、バージョンによって回答内容が異なる場合もありますので・・・
大丈夫だとは思うけど
ヘッダファイルに定義されているものだから
EXEとDLLで_bstr_tの中身が変わっていたらやだなあ。
異なる動作をしたらトラブル起こすよ。
bstrVal.operator =
じゃなくて
bstrVal =
でいいはずだけど。
EXEとDLLでデバッグ版とリリース版あるいは
MFC??.DLLあるいはそのほかのDLLかDLLではないライブラリ
などが混在すると
別の実態がメモリ確保と解放をおこなうので問題になるよ。
DLLにするなら互換性のあるBSTRにすべき。
みなさま、おはよございます。
レスありがとうございます。
どら様のおっしゃっている内容にて確認してみましたが、結果は変わりませんでした。
wclrp ( 'o') 様
>DLLにするなら互換性のあるBSTRにすべき。
こちらの方向で考えて行きたいと思います。
それと
>別の実態がメモリ確保と解放をおこなうので問題になるよ。
なのですが、別の実態とはどのようなことなのでしょうか?
たしかに、2回目の関数を呼んで_bstr_tに文字列を入れる時にその領域を一度deleteしててその時にアサートがでている感じです。
なんかまずいことが起きているとは思うのですが・・・(以下のdeleteです)
ーーーーー-------------------------------------------------
inline unsigned long _bstr_t::Data_t::Release() throw()
{
if (!InterlockedDecrement(reinterpret_cast<long*>(&m_RefCount))) {
delete this; <-ここです
return 0;
}
return m_RefCount;
}
ーーーーー-------------------------------------------------
ちなみに、開発環境は以下のとおりになります。
Windows2000、VS6.0。
DLL側:Win32 Dynamic-Link Library(ビルド環境はdebug)
EXE側:Win32 Console Applecation(ビルド環境はdebug)
http://madia.world.coocan.jp/cgi-bin/Vcbbs/wwwlng.cgi?print+200710/07100022.txt
と同じことが bstr_t の中で起こっているわけだ
なので、EXE/DLL をまたがるインターフェイスに使う型としては
コンパイルオプション等によらず互換性がある (ありそうな) 単純な型が良い、
ということなわけ。
DLL と EXE でスレッドモデルが違ったりしてないか?
DLL 開発完了後に行う、別の EXE の開発の際に VS2005 等に乗り換えたりしないか?
その DLL を他人に使わせる可能性は無いか?
その他人は BCC や GCC で開発したりはしないか?ということだ
tetrapod様、ならびにレスくださった方々。
ありがとうございました。
とりあえず、DLLにするか、LIBのままにするか検討して対応して行きたいと思います。
いまの段階だとDLLのパラメータを互換性のある型にする方向です。
ツイート | ![]() |