DLLの呼び出し終了時の初期化

解決


番頭  2006-05-09 18:17:31  No: 21423

はじめまして、番頭と申します。
DelphiのFormat文をC#で利用する為、
以下のような内容のDLLを作成しました。

↓ここから
uses
  SysUtils,
  Classes,
  Dialogs,
  Windows;

{$R *.RES}

function DelphiFormat(var FormatString:PChar; OutStr:PChar; Value:double ):boolean; stdcall;
var
   len:integer;
   tempLong:longint;
   tempFormat:String[255];
   tempBuf:String[255];
   LastChar:String[1];
begin

   try
       tempFormat:=FormatString;

       if Pos('%', tempFormat)>0 then
       begin
           LastChar := ANSIUpperCase(Copy(tempFormat,Length(tempFormat),1));
           if(LastChar='X') or (LastChar='D') or (LastChar='U') then
           begin
               tempLong := Round(Value);
               tempBuf:=Format(tempFormat,[tempLong]);
           end
           else
           begin
               tempBuf:=Format(tempFormat,[Value]);
           end;
       end
       else
       begin
          tempBuf:=FormatFloat(tempFormat, Value);
       end;

       len:=Length(tempBuf);
       if(OutStr<>nil)and(len>0) then
       begin
           StrPCopy(OutStr, tempBuf);
       end;
       Result:=true;
   except
       On E:Exception do
       begin
           Result:=false;
       end;
   end;

end;
exports
   DelphiFormat;
begin
end.
↑ここまで
C#側で上記DLLを次のように利用しています。
↓ここから

//  宣言部
[DllImport("FormatValue.dll", 
            CharSet = CharSet.Ansi  , 
            CallingConvention = CallingConvention.StdCall)]
        private static extern bool DelphiFormat( ref string FormatString, StringBuilder OutStr, double inputValue );

//  利用部:TextBoxで指定した書式でTextBox2の値を書式変換
    string formatString = textBox1.Text;
    StringBuilder outStr = new StringBuilder(256);
    double inputValue = double.Parse(textBox2.Text);

    if (DelphiFormat(ref formatString, outStr, inputValue))

↑ここまで

この条件で、C#のプログラムを繰返して実行すると、
タスクマネージャで見た場合、「ページファイルの使用量」が
時間と共に増加していきます。

同じプログラムで、DLL利用部をコメントアウトすると、
ページファイルの増加はありませんでした。
結果として、DLLの中でメモリリークをしているようなので、
終了時に使用メモリを正しく開放したいのですが、
やり方が良く分かりません。

どなたかご存知でしたら、教えていただきたいのですがm(__)m


free  2006-05-09 18:39:27  No: 21424

>    StringBuilder outStr = new StringBuilder(256);
これがどんどんメモリ侵食してるのかも?


番頭  2006-05-09 19:09:16  No: 21425

freeさま
回答ありがとうございます。
StringBuilderですが、
ルーチンを抜ける時にFrameworkの方で開放しているようです。
StringBuilder outStr = new StringBuilder(256);
を残して
if(DelphiFOrmat(・・・
の部分のみコメントアウトした状態だと問題は発生しませんでした。

後,開発環境について説明が足りなかったのですが、
DLLはDelphi5.0
C#はVisualStudio 2005 .Net Framework 2.0
でOS はWindows XP Professional SP2
で行っています。


free  2006-05-09 19:18:54  No: 21426

そういうことなら、仮に、dll のほうのルーチンをカラにするとか、単に文字列をを返すだけにしてテストしてみたらどうかなぁ? どちらが原因かを確定すると、見るべきガワがわかるかも。詳しくなくてスマソ。


番頭  2006-05-10 02:15:47  No: 21427

自己解決しました。

処理の結果に影響しないので、
引数の宣言を見直しました。

DLL側の第一引数
var FormatString:PChar

FormatString:PChar

C#側の宣言部の
ref string FormatString, 

string FormatString, 
に変更したらページフォルトの増大はしなくなりました。
お騒がせいたしました。

でもなぜ???


**  2006-05-10 03:21:16  No: 21428

var FormatString:PChar;
**FormatString

FormatString:PChar;
*FormatString


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加