はじめまして、番頭と申します。
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
> StringBuilder outStr = new StringBuilder(256);
これがどんどんメモリ侵食してるのかも?
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
で行っています。
そういうことなら、仮に、dll のほうのルーチンをカラにするとか、単に文字列をを返すだけにしてテストしてみたらどうかなぁ? どちらが原因かを確定すると、見るべきガワがわかるかも。詳しくなくてスマソ。
自己解決しました。
処理の結果に影響しないので、
引数の宣言を見直しました。
DLL側の第一引数
var FormatString:PChar
を
FormatString:PChar
に
C#側の宣言部の
ref string FormatString,
を
string FormatString,
に変更したらページフォルトの増大はしなくなりました。
お騒がせいたしました。
でもなぜ???
var FormatString:PChar;
**FormatString
FormatString:PChar;
*FormatString
ツイート | ![]() |