none
MFC 自作コントロールのRelease版DLLをDebug環境で使うとアサートする RRS feed

  • 質問

  • いつもお世話になっております。

    MFCのCScrollView派生のコントロールを作りMFC拡張DLLにしました。クラス名はCHogeViewとします。
    MFC AppWizard(exe)でSDIのサンプルアプリ(CHogeSample)を作りこのDLLをリンクしてビュークラスをCHogeView派生としました。
    このときRelease環境ではReleaseビルドのDLL,Debug環境ではDebugビルドのDLLにすれば正常に動作するのですが、Debug環境でReleaseビルドのDLLを使おうとすると実行時にInitInstanceのドキュメントテンプレート登録でassertします。

    pDocTemplate = new CSingleDocTemplate(
    IDR_MAINFRAME,
    RUNTIME_CLASS(CHogeSampleDoc),
    RUNTIME_CLASS(CMainFrame),
    RUNTIME_CLASS(CHogeSampleView));

    CDocTemplateコンストラクタの以下のアサートで引っかかっているようです。
    ASSERT(pViewClass == NULL ||
    pViewClass->IsDerivedFrom(RUNTIME_CLASS(CView)));

    ReleaseビルドのDLLはDebug環境ではドキュメントテンプレート登録して使えないものなのでしょうか?
    なぜDebugビルドのDLLにしないかというと、このDLLは公開したいのですがソースは公開したくないので
    DebugのDLLは外にだしたくないからです。

    どなたかなんでも結構ですので情報をお持ちの方いらっしゃれば教えていただけないでしょうか?
    よろしくお願いします。

    2009年9月1日 9:51

回答

  • jzkeyさんが書かれた流れで合っています。Debug版DLLのデバッグ情報にはソースが含まれるものと思っていましたがそうではないのでしょうか?

    >C++のクラスの入ったdllをバイナリのみで配布・メンテすること自体それなりに骨ですが(C++にはバイナリ互換が
    >ほとんどないからこそのCOM/ActiveXですし)、それを考慮済みというなら
    >
    C++のクラスをDLLバイナリで配布というのは今まで何度もやっていることなので問題ないと思いますが、MFCクラスをDLLで公開するのは今回がはじめてなのでとまどっています。一般的にMFCクラスをDLLバイナリで配布している個人、企業はほとんどない?ようですね。
    >DebugのDLLを公開しないこととソースを公開しないこととどう繋がるのか理解できませんでした。
    Debug版のDLLはあくまでもソースの位置を内部に持っているだけでソースその物を持っているわけでは有りません。
    ですから、Debug版のDLLだけを公開してソースを配らないとDLLの中までデバッガで入る事は出来ません。
    これに関しては実際に自分の環境で試してみれば、すぐにわかりますよ。
    DLLの中にファイルの位置も持っているのでソースが入っているディレクトリを動かしてしまうと
    自分の開発環境でもうまくデバッガで追えなくなるはずです。

    jzkeyさんが書かれているようにDLLバイナリでの配布の場合、コンパイラのバージョンが合わないと問題になるので
    各コンパイラのバージョン毎にDLLを用意するハメになりますよね。その部分の事を大変だと言われているのだと思います。

    jzkeyさんが書かれているようにコンパイラのバージョン等を気にしなくても良いように一般的なコンポーネントを売っている会社は
    COMの形式で出している事が多いと思います。特にMFCの拡張DLLの場合はコントロール系が多くなるのでCOMで公開している
    ケースの方が多いのではないでしょうか。そうでなければ、オープンソースでソース毎公開しているかでしょう。


    解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
    • 回答としてマーク ひろ太 2009年9月2日 13:10
    2009年9月2日 3:05

すべての返信

  • DebugのDLLを公開しないこととソースを公開しないこととどう繋がるのか理解できませんでした。
    どのような解釈から、両者が連動するとお考えなのでしょうか?
    • 回答としてマーク ひろ太 2009年9月2日 13:10
    • 回答としてマークされていない ひろ太 2009年9月2日 13:11
    2009年9月1日 10:29
  • ・市販ActiveXコンポーネントのような、「MFCによるコンポーネント」を作成・配布したい
    ・Release版MFCとリンクしたDLL(とヘッダ)のみ配布すればいいのでは
    ・そうすると、その配布をうけたユーザーがデバッグできない
    ・debug版のdll(debug版MFCにリンク)を配布すると、デバッグ情報から元ソースの情報が漏れるのでは
    という流れでしょうか。

    C++のクラスの入ったdllをバイナリのみで配布・メンテすること自体それなりに骨ですが(C++にはバイナリ互換が
    ほとんどないからこそのCOM/ActiveXですし)、それを考慮済みというなら、Releaseのコード生成と
    同のコンパイルオプションを付けて、debug版MFCとリンクしたdll/libも配布する手があるとおもいますよ。

    jzkey
    2009年9月1日 12:44
  • 佐祐理さん、jzkeyさん返信ありがとうございます。

    >DebugのDLLを公開しないこととソースを公開しないこととどう繋がるのか理解できませんでした。
    >どのような解釈から、両者が連動するとお考えなのでしょうか?
    jzkeyさんが書かれた流れで合っています。Debug版DLLのデバッグ情報にはソースが含まれるものと思っていましたがそうではないのでしょうか?

    >C++のクラスの入ったdllをバイナリのみで配布・メンテすること自体それなりに骨ですが(C++にはバイナリ互換が
    >ほとんどないからこそのCOM/ActiveXですし)、それを考慮済みというなら
    >
    C++のクラスをDLLバイナリで配布というのは今まで何度もやっていることなので問題ないと思いますが、MFCクラスをDLLで公開するのは今回がはじめてなのでとまどっています。一般的にMFCクラスをDLLバイナリで配布している個人、企業はほとんどない?ようですね。
    • 回答としてマーク ひろ太 2009年9月2日 13:10
    • 回答としてマークされていない ひろ太 2009年9月2日 13:11
    2009年9月2日 1:19
  • jzkeyさんが書かれた流れで合っています。Debug版DLLのデバッグ情報にはソースが含まれるものと思っていましたがそうではないのでしょうか?

    >C++のクラスの入ったdllをバイナリのみで配布・メンテすること自体それなりに骨ですが(C++にはバイナリ互換が
    >ほとんどないからこそのCOM/ActiveXですし)、それを考慮済みというなら
    >
    C++のクラスをDLLバイナリで配布というのは今まで何度もやっていることなので問題ないと思いますが、MFCクラスをDLLで公開するのは今回がはじめてなのでとまどっています。一般的にMFCクラスをDLLバイナリで配布している個人、企業はほとんどない?ようですね。
    >DebugのDLLを公開しないこととソースを公開しないこととどう繋がるのか理解できませんでした。
    Debug版のDLLはあくまでもソースの位置を内部に持っているだけでソースその物を持っているわけでは有りません。
    ですから、Debug版のDLLだけを公開してソースを配らないとDLLの中までデバッガで入る事は出来ません。
    これに関しては実際に自分の環境で試してみれば、すぐにわかりますよ。
    DLLの中にファイルの位置も持っているのでソースが入っているディレクトリを動かしてしまうと
    自分の開発環境でもうまくデバッガで追えなくなるはずです。

    jzkeyさんが書かれているようにDLLバイナリでの配布の場合、コンパイラのバージョンが合わないと問題になるので
    各コンパイラのバージョン毎にDLLを用意するハメになりますよね。その部分の事を大変だと言われているのだと思います。

    jzkeyさんが書かれているようにコンパイラのバージョン等を気にしなくても良いように一般的なコンポーネントを売っている会社は
    COMの形式で出している事が多いと思います。特にMFCの拡張DLLの場合はコントロール系が多くなるのでCOMで公開している
    ケースの方が多いのではないでしょうか。そうでなければ、オープンソースでソース毎公開しているかでしょう。


    解決した時は、参考になったレスポンスの所にある[回答としてマーク]ボタンをクリックしてスレッドを締めましょう。
    • 回答としてマーク ひろ太 2009年9月2日 13:10
    2009年9月2日 3:05
  • 返信をくださった皆様ありがとうございました。
    デバッグDLLにソースは含まれていないということでDebug版DLLを配布するようにします。
    ありがとうございました。_(__)_
    2009年9月2日 13:13
  • >Debug版DLLを配布するようにします。

    そんなことしちゃダメです。
    Debug 版の VC++ ランタイムをリンクした生成物を再配布することは禁じられていたはずです。

    再配布物のデバッグ可用性?を高めたいなら、Release ビルドのコンパイラ最適化を弱める+デバッグ情報を追加+再配布物に .pdb を含めるのがよろしいんじゃないかと思います。
    2009年9月3日 0:50
  • はて。「デバッグ版ランタイムをリンクした生成物」の配布を禁じる規定はeulaには見る限りなかったです。
    もちろん、「デバッグ版ランタイム(DLL)」そのものは、redist.txtの対象外なので配布禁止ですので
    VisualStudioを所持していない人では実行できないでしょうけれども。

    jzkey
    2009年9月3日 11:52
  • 確か・・・
    VCのバージョンにもよるでしょうが、debug版だと一定回数mallocしたらクラッシュするとかあったような・・・
    (mallocの回数とfreeの回数をカウントしてメモリ解放が正しく行えているか確認する機構なんですが、カウンタがあふれたときにクラッシュするという現象があったような・・・自分のコードの中でmallocを使っていなくてもランタイムの中で使用されていれば同じなのでdebug版を正式に使用するのは避けた方がよいです。)
    ほかにも常用できない問題を持っている可能性もあります。
    2009年9月3日 13:35
  • >はて。「デバッグ版ランタイムをリンクした生成物」の配布を禁じる規定はeulaには見る限りなかったです。
    >もちろん、「デバッグ版ランタイム(DLL)」そのものは、redist.txtの対象外なので配布禁止ですので
    >VisualStudioを所持していない人では実行できないでしょうけれども。

    そうでした。
    成果物そのものの配布が禁じられているわけではありませんでした。

    ランタイムを静的リンクした場合はどうなるんでしたっけ?
    2009年9月3日 17:17
  • ランタイムを静的リンクした場合はどうなるんでしたっけ?
    ダメという記述は見つけられませんね。
    「再頒布可能なもの以外を再頒布するな。」となっているだけで。

    ただ、MFCを改変した独自MFCのDLLを頒布することは可能ですが、MFCのテクニカルノート 33でデバッグバージョンの頒布は禁止されているので、静的リンクも実はダメなのかもしれません。

    デバッグバージョンのものを本番で使うのは避けるべきだとは思いますが。
    2009年9月4日 1:03