喫茶XRAYトップページ

[スレッド全体
]

[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