喫茶XRAYトップページ

[スレッド全体
]

[12308] メモリの不正アクセスの結果返信 削除
2018/9/20 (木) 23:23:44 Mr.XRAY
▼ Mr.XRAYさん
> [DLL上の例外をコピーした文字列をFreeLibraryにアクセスとエラーになる]
> http://madia.world.coocan.jp/cgi-bin/DelphiBBS/wwwlng.cgi?print+201809/18090005.txt
>
> >AAA 2018/09/20(木) 21:58:42 書込者ID:[ 26FSmWST1pEdhB1L06XZlQ ]
> >そんなに質問の内容を理解できていなかった事を指摘されて
> >悔しいですか?
>
> はい,悔しいです.なわけないでしょうが.


喫茶XRAY のお客様には既知のことと思いますが.
アクセスの内容にもよるかも知れませんが,
一般的には,メモリの不正アクセスの結果を予測することはできません.
これは,配列の範囲外操作でも同じです.

もちろん
「メモリアクセス違反の例外が発生するかも知れない」
という予測はなしです (笑)


[12309] Re:メモリの不正アクセスの結果返信 削除
2018/9/21 (金) 11:29:01 Mr.XRAY
> 一般的には,メモリの不正アクセスの結果を予測することはできません.
> これは,配列の範囲外操作でも同じです.


メモリアクセス違反の例外 (デバッガ例外通知) が発生したら,
例外が発生する状態のままで取得した結果の原因を調べることに意味は
ほとんど (あるいは全く) ないということです.
それよりも例外が発生しないようにすることが最優先ということです.

Mr.XRAY 2018/09/20(木) 21:41:01
Mr.XRAY 2018/09/20(木) 21:48:43

のレスは,嫌味というかちょっとばかり意地悪のつもりで書き込んでしまいました.
スレッド汚しですね.私の悪い性格です m(_ _)m


[12310] Re2:メモリの不正アクセスの結果返信 削除
2018/9/21 (金) 13:42:03 taka
▼ Mr.XRAYさん
> > 一般的には,メモリの不正アクセスの結果を予測することはできません.
> > これは,配列の範囲外操作でも同じです.
>
> メモリアクセス違反の例外 (デバッガ例外通知) が発生したら,
> 例外が発生する状態のままで取得した結果の原因を調べることに意味は
> ほとんど (あるいは全く) ないということです.
> それよりも例外が発生しないようにすることが最優先ということです.
>
> Mr.XRAY 2018/09/20(木) 21:41:01
> Mr.XRAY 2018/09/20(木) 21:48:43
>
> のレスは,嫌味というかちょっとばかり意地悪のつもりで書き込んでしまいました.
> スレッド汚しですね.私の悪い性格です m(_ _)m


まとめ
・ShareMemは使わない
・DLLの戻り値型関数で戻り値を返さず例外は投げる
・例外は、呼び出し側のtry exceptでキャッチする
・ポインタを使うと違反は発生しない

最初の投稿で
ポインタを使うと違反は発生しない
ことを示しておいて

共有メモリや
標準的なDLLの仕様を教えると 聞く耳持たず

ASさんと同じで
「Delphiのバグ」という回答が欲しかったのでしょう。



[12311] Re3:メモリの不正アクセスの結果返信 削除
2018/9/21 (金) 14:07:21 Mr.XRAY
> ASさんと同じで
> 「Delphiのバグ」という回答が欲しかったのでしょう。


そうか,そういうことなんですね.
気づかないで悪いことしてしまいました.ゴメンナさい (笑)


[12312] Re4:メモリの不正アクセスの結果返信 削除
2018/9/21 (金) 14:57:00 taka
▼ Mr.XRAYさん
> > ASさんと同じで
> > 「Delphiのバグ」という回答が欲しかったのでしょう。
>
> そうか,そういうことなんですね.
> 気づかないで悪いことしてしまいました.ゴメンナさい (笑)



Win32版 エラーになる「無効なポインタ操作.」。
  PChar(E.Message)にすると エラーにはならない。

Unicode版 エラーにはならない。

EXE(unicode),DLL(win32) アドレス00000000 なんとか違反で 例外処理すら許されない。
EXE(win32), DLL(unicode) アドレス00000000 なんとか違反。


まとめ(非推奨): DLLの関数から例外を投げる (sharememは使わない場合)
・どうしても投げたいなら、exe,dll 同じバージョンでコンパイルする
 except on E: Exception do
   begin
     S := E.Message;  // この段階では同じアドレスを指している。どちらかの内容が変更されない限り同じアドレスを指す
     UniqueString(S); // 新しいアドレスに文字列を複製する
   end;
 end;

 S := string(PChar(E.Message));
 S := StrUtils.LeftStr(E.Message, Length(E.Message));
 S := Copy(E.Message, 1, Length(E.Message));
を使っても文字列を複製しなおすことができる

ついでなので Lazarusでやってみると、
Stack overflow が発生し 2回以上実行すると暴走。

普通の人は、
DLLで発生した例外は、きちんとDLL内で処理しよう。外におもらししないこと


[12317] Re5:メモリの不正アクセスの結果返信 削除
2018/9/21 (金) 18:14:25 Mr.XRAY
▼ takaさん

>   PChar(E.Message)にすると エラーにはならない。

そうなんですよ.AAA さんが提示したコードで気づきました.

S := E.Message + 'XXXX';

string 型の文字列を + しているので E.Message は暗黙の型キャストですね.多分.
なら PChar で OK でしょう ? というわけです.

今回の場合はこれで OK なんですが,
実はこの他に何かの操作をすると問題が発生する,
というのが以前どこかのコミュニティの場であったんです.
内容は失念しました.Ansi 版と Unicode 版の違いだったのかも.

>・どうしても投げたいなら、exe,dll 同じバージョンでコンパイルする

基本的にはすべきではないてすね.
DLL は別プロセスでの実行なので (笑) <--- ここだけの秘密です !!


[▼次のスレッド]
INCM/CMT
Cyclamen v3.82