とりあえず、ぱっと見での回答です。
UNLHA32.DLLの、UnlhaOpenArchive()とかUnlhaExtractMem()の扱う文字列はMBCS限定
です。
TCHARとか_Tマクロなど、使ってはなりません。
UnlhaFindFirst()系のAPIは先頭を返しますが、FindNext系で回して情報を取得するの
で、いきなりUnlhaCloseArchive()を呼んではなりません。
少なくともオリジナルの全体サイズなどは、ぐるっと1週走査しないと、正しい値が保
障されなかったように記憶しております。
(他の統合アーカイバDLLも似たような制限があります)
そういった制限はUNLHA32.DLLのドキュメントに事細かに記載してあるので、再確認す
ることをお勧めします。
> その通りです。
> 参考にしたサンプルが WinAPI で、これらはグローバル変数となっています。
> 自分のプログラムはMFCで、これらの変数は一つの関数の中だけで使っていて、 記
号
>をそのままにしているだけです。
> BYTE* g_buf = new BYTE[g_len + 1];
も関数の中で使っているみたいですね。
なので
>if (g_buf) delete [] g_buf;
があるのですね。
関数のなかで、毎回new文を使うのはよくないですね。
HeapCreate等を使って、
関数内は容量変更と内容消去のみを行なった方がいいですね。
オブジェクトの作成と解放は関数の外で1回だけ行なうようにしたほうがいいですね。
UnlhaExtractMem の第5、第6引数に、非 NULL な変数のアドレスを渡してみるとどうで
しょうか。
ドキュメントでは NULL が指定できることになっていますが、案外…
> UNLHA32.DLLの、UnlhaOpenArchive()とかUnlhaExtractMem()の扱う文字列はMBCS限定
です。
> TCHARとか_Tマクロなど、使ってはなりません。
最新版 v2.67a に付属の Unlha32.h であれば、UNICODE マクロが定義されているとき、
UnlhaExtractMem は UnlhaExtractMemW に置き換えられます。
aetos様
> UnlhaExtractMem の第5、第6引数に、非 NULL な変数のアドレスを渡してみると
> どうでしょうか。
これは前にやってみていたのですが、結果は同じで、アクセス違反でした。
自分が作っているプロジェクトは「UNICODE文字を使用する」です。
お手上げ状態です。
HeapCreateも色々トライしてみましたが、ビルドできません。やり方が解っていないた
めです。
ところで、自分のプログラムは 32bitアプリケーションとして普通に作っているのです
が、64bit でも動作するらしく使って貰っています。
この UNLHA32.DLL を使った解凍の機能を追加できたとして、64bit では動作しないので
しょうか?
そうであれば、もう諦めます。
64bitのDLLは基本的に32bitアプリケーションから読み込めません。
UNLHA64.DLLが開発中という話は聞きますが、登場時期は作者のみぞ知るという状況で
すね。
とりあえず統合アーカイバプロジェクトのDLLはUNICODE対応が芳しくないので、非
UNICODEアプリにした方が問題を起こしにくいです。
問題部分を切り出して、別のアプリで検証すると良いですよ。
無論、文字コードをちゃんと考慮して使い分けができるようになるのが最善なんです
が・・・。
AR様
> 64bitのDLLは基本的に32bitアプリケーションから読み込めません。
話は逆です。
UNLHA32.DLL を 32bitアプリケーションに組み込んだとき、64bit OS で動作するかどう
か心配しています。
> UNLHA64.DLLが開発中という話は聞きますが、登場時期は作者のみぞ知るという状況
> ですね。
UNLHA64.DLL の開発は中止が決まっています。理由は、lzhファイルにセキュリティ上の
弱点があるからと聞いています。
にもかかわらず、lzh 形式で配布されているファイルがあり、それを解凍する機能を、
自分のアプリに追加したいのです。
>UNLHA32.DLL を 32bitアプリケーションに組み込んだとき、64bit OS で動作するかど
うか心配しています。
問題ありません。
世間に出回っているUNLHA32.DLLを直接使用しているアプリケーションはすべて32ビッ
トアプリケーションです、ということを言ってます。
>UNLHA64.DLL の開発は中止が決まっています。理由は、lzhファイルにセキュリティ上
の弱点があるからと聞いています。
あらら、あの騒動の後にも64ビット版を作成される旨の発言されていたのですが、ど
うも状況が変わっていたようですね。
失礼しました。
ただ、そのままの形は出さないという表現ですし、決め付けるのはちょっと抵抗あり
ますね。
AR様、失礼しました。そういう意味だったのですね。
UNLHA64.DLL開発のところも、失礼しました。訂正します。
Micco氏のホームページのこのページ
http://homepage3.nifty.com/micco/incidents/2011/inci1101.htm
長い、このページの一番下の方
「Jan.07,2011 64 ビット版 DLL, 2011 年の展望... 」
の中に次の文章があります。
・今年の上半期中には 64 ビット版を出すことになると思います,
・その場合は「UNLHA64.DLL」ではなくて「UNLHA32.DLL for x64」になると思います。
・現行の仕様のまま UNLHA64.DLL を出す気はありません。
Visual Studio 2005 をインストールして同じことをやってみました。
やはり同じで、UnlhaExtractMem が実行されるときにアクセス違反が生じます。
ファイルの解凍結果は正しいです。
アクセス違反を無視しようと思います。
その場合、どんな弊害があるのでしょうか?
>HeapCreateも色々トライしてみましたが、ビルドできません。やり方が解っていないた
めです。
うーーん、HeapCreateだけにこだわっていません。
ただ問題にしたかったのは、new文はその都度初期化するのはよくないです。
ファイルの容量を調べて、その都度容量を変えたい希望みたいなので、HeapCreate等の
容量が可変できるメモリーオブジェクトがいいのかと思い、すすめました。
HeapCreate以外に確変さんが使い慣れているのがあればそちらでいいと思います。
LPBYTE g_buf = (LPBYTE)GlobalAlloc(GMEM_FIXED, g_len+1);
としてやってみたのですが、やはりアクセス違反となりました。
第1変数は、GHND、GPTR、GMEM_MOVEABLE も試しました。
> 確変 2012/04/30(月) 11:31:42
この書き込みを見る限り、例外が生じるのは別の箇所なのでは ?
例外を必ず発生させることができますか。
もし、そうならば、
例外-->中断
メニュー-->デバッグ-->ウィンドウ-->呼び出し履歴
(VS2003の場合。VS2010だとステップは違うかもしれないが、呼び出し履歴を出す)
幸運ならば、呼び出し履歴画面からソースが表示できるかも知れません。
ソースが表示できれば、その部分か少し前の部分にブレークポイントを置いて、
再度実行。
問題箇所のソースが不明でも、
ブレークポイントを置き直すか、ステップ実行するか、トレースして、
まずは例外の発生する箇所を特定すべきと思います。
ロマ様
> この書き込みを見る限り、例外が生じるのは別の箇所なのでは ?
間違いなく UnlhaExtractMem() を実行したときアクセス違反が生じています。
> 例外を必ず発生させることができますか。
はい。
> 例外-->中断
中断しません。最後まで進み、正しい解凍内容がメモリに入っています。
> メニュー-->デバッグ-->ウィンドウ-->呼び出し履歴
「呼び出し履歴」が見当たりません。メニューの全部とオプションも探しました。
VS2010 Professional および VS2005 Team Edition のどちらもです。
「ウィンドウ」の中にあるのは、「ブレイクポイント」「出力」「イミディエイト」の
3つです。
既定で「出力」ウィンドウが出ていて、デバッグ時のイベントが表示されます。
ここに「0x760e7ee4 で初回の例外が発生しました: 0xC0000005: 場所 0x00000000 を読
み込み中にアクセス違反が発生しました。」と出ます。
> 問題箇所のソースが不明でも、
> ブレークポイントを置き直すか、ステップ実行するか、トレースして、
> まずは例外の発生する箇所を特定すべきと思います。
UNLHA32.DLL のソースは公開されていません。
色々やっても、関数 UnlhaExtractMem() を展開して見ることが出来ませんでした。
私が取り違えていたようです。
実行中に例外が出るのかと思っていました。
Debugで実行すると、プログラムは正常に終了し、
終了後に出力ウィンドウをみると例外メッセージがでるということですか。
だとすると、
try/catchで例外を処理しているのではないでしょうか。