Delphi7を使用しています。
exeで構造体に文字列を入れてdllに送って処理をさせようと
考えているのですが、dllで受け取った構造体の文字がうまく
返ってきません。
type
TNotes = record
A : array[0..255] of char;
B : array[0..255] of char;
C : array[0..255] of char;
D : array[0..255] of char;
E : array[0..255] of char;
F : array[0..255] of char;
G : array[0..255] of char;
end;
上記の構造体に
StrPLCopy(Notes.A ,'AA',Sizeof(Notes.A));
StrPLCopy(Notes.B ,'BB',Sizeof(Notes.B));
StrPLCopy(Notes.C ,'CC',Sizeof(Notes.C));
StrPLCopy(Notes.D ,'DD',Sizeof(Notes.D));
StrPLCopy(Notes.E ,'EE',Sizeof(Notes.E));
StrPLCopy(Notes.F ,'FF',Sizeof(Notes.F));
StrPLCopy(Notes.G ,'GG',Sizeof(Notes.G));
といったやり方で,構造体をdllに送ってやってるのですが、
dllから値をshowmessageしてみるとA,B,Cしか戻ってきません。
正しく格納されてないからじゃないかと考えているのですが、
どこがおかしいのか分からず悩んでいます。
もしご存知の方がいらっしゃったらご教授頂けないでしょうか?
>といったやり方で,構造体をdllに送ってやってるのですが、
どういったやり方?dllに送っているというソースがないですよね
もっと詳しく(分かりやすく)説明していただけませんか?
申し訳ありません。
function du_SendMail (var FNotes : TNotes): LongInt;stdcall;
dll側では同じ構造体を用意して上記のような関数を作成しているので
exe側で呼び出して使用しています。
dllのfunction内でFNotesのA,B,Cはshowmessageで表示出来たのですが
他の項目が空(?)なのでうまく格納されていないと思っているのです。
Delphi5Pro, Delphi7Pro で試したのですが、
正しく値が格納されていました。
exe側
procedure TForm1.Button3Click(Sender: TObject);
var
Notes: TNotes;
begin
StrPLCopy(Notes.A ,'AA',Sizeof(Notes.A));
StrPLCopy(Notes.B ,'BB',Sizeof(Notes.B));
StrPLCopy(Notes.C ,'CC',Sizeof(Notes.C));
StrPLCopy(Notes.D ,'DD',Sizeof(Notes.D));
StrPLCopy(Notes.E ,'EE',Sizeof(Notes.E));
StrPLCopy(Notes.F ,'FF',Sizeof(Notes.F));
StrPLCopy(Notes.G ,'GG',Sizeof(Notes.G));
du_SendMail(Notes);
end;
dll側
function du_SendMail(var FNotes : TNotes): LongInt; stdcall;
var
S: String;
begin
S := 'A:' + FNotes.A + Chr($d) + Chr($a) +
'B:' + FNotes.B + Chr($d) + Chr($a) +
'C:' + FNotes.C + Chr($d) + Chr($a) +
'D:' + FNotes.D + Chr($d) + Chr($a) +
'E:' + FNotes.E + Chr($d) + Chr($a) +
'F:' + FNotes.F + Chr($d) + Chr($a) +
'G:' + FNotes.G;
MessageDlg(S, mtInformation, [mbOk], 0);
Result := 0;
end;
igyさん、ありがとうございます。
私もDelphi7Proを使っているのですが、やはりD,E,F,Gは戻ってきません。
dllでは、Showmessage(String(FNotes.A));
というようにA〜Gを出していたのですが表示されたのはA,B,Cだけなんです。
igyさんの書かれたものを使用してみても結果は同じでした。
Exe側でShowmessage(String(FNotes.A));などでは表示されるので
何か問題があるのかと思っていました。(特に長さ)
またExcelなどのVBAより同じDllを呼び出すとちゃんと表示されます。
こちらで試したプログラムは以下のとおりです。
exe側
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;
type
TNotes = record
A : array[0..255] of char;
B : array[0..255] of char;
C : array[0..255] of char;
D : array[0..255] of char;
E : array[0..255] of char;
F : array[0..255] of char;
G : array[0..255] of char;
end;
TForm1 = class(TForm)
Button3: TButton;
procedure Button3Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
function du_SendMail(var FNotes : TNotes): LongInt; stdcall; external 'TESTDLL1.DLL';
procedure TForm1.Button3Click(Sender: TObject);
var
Notes: TNotes;
begin
StrPLCopy(Notes.A ,'AA',Sizeof(Notes.A));
StrPLCopy(Notes.B ,'BB',Sizeof(Notes.B));
StrPLCopy(Notes.C ,'CC',Sizeof(Notes.C));
StrPLCopy(Notes.D ,'DD',Sizeof(Notes.D));
StrPLCopy(Notes.E ,'EE',Sizeof(Notes.E));
StrPLCopy(Notes.F ,'FF',Sizeof(Notes.F));
StrPLCopy(Notes.G ,'GG',Sizeof(Notes.G));
du_SendMail(Notes);
end;
end.
--------------------------------------------------
dll側(TESTDLL1.dpr)
library TESTDLL1;
uses
SysUtils,
Classes, Dialogs;
type
TNotes = record
A : array[0..255] of char;
B : array[0..255] of char;
C : array[0..255] of char;
D : array[0..255] of char;
E : array[0..255] of char;
F : array[0..255] of char;
G : array[0..255] of char;
end;
function du_SendMail(var FNotes : TNotes): LongInt; stdcall;
var
S: String;
begin
S := 'A:' + FNotes.A + Chr($d) + Chr($a) +
'B:' + FNotes.B + Chr($d) + Chr($a) +
'C:' + FNotes.C + Chr($d) + Chr($a) +
'D:' + FNotes.D + Chr($d) + Chr($a) +
'E:' + FNotes.E + Chr($d) + Chr($a) +
'F:' + FNotes.F + Chr($d) + Chr($a) +
'G:' + FNotes.G;
MessageDlg(S, mtInformation, [mbOk], 0);
Result := 0;
end;
exports
du_SendMail;
begin
end.
// 宣言部
type
TChar255 = array[0..255] of char;
TNotes = record
A : TChar255;
B : TChar255;
C : TChar255;
D : TChar255;
E : TChar255;
F : TChar255;
G : TChar255;
end;
// exe 側
procedure TForm1.Button3Click(Sender: TObject);
var
Notes: TNotes;
begin
FillChar(Notes, SizeOf(TNotes), 0);
(略)
du_SendMail(Notes);
end;
// dll 側
function Char255toText(aChar255: TChar255): String;
var
i,j: Integer;
begin
Result := '';
for i := 0 to 15 do begin
for j := 0 to 15 do begin
Result := Result + ' ' + IntToHex(Ord(aChar255[i*16 + j]), 2);
end;
Result := Result + #$D#$A;
end;
end;
function du_SendMail(var FNotes : TNotes): LongInt; stdcall;
var
noteStr: String;
begin
MessageDlg('A' + #$D#$A + Char255toText(FNotes.A), mtInformation, [mbOk], 0);
MessageDlg('B' + #$D#$A + Char255toText(FNotes.B), mtInformation, [mbOk], 0);
MessageDlg('C' + #$D#$A + Char255toText(FNotes.C), mtInformation, [mbOk], 0);
MessageDlg('D' + #$D#$A + Char255toText(FNotes.D), mtInformation, [mbOk], 0);
MessageDlg('E' + #$D#$A + Char255toText(FNotes.E), mtInformation, [mbOk], 0);
MessageDlg('F' + #$D#$A + Char255toText(FNotes.F), mtInformation, [mbOk], 0);
MessageDlg('G' + #$D#$A + Char255toText(FNotes.G), mtInformation, [mbOk], 0);
Result := 0;
end;
これで、実際のデータを確認してみるとどうでしょう?
とりあえず、D5環境で、igyさん同様、変なデータになりません。
入力した内容が、そのまま受け渡しされています。
igyさん、ん?さん、ありがとうございます。
ソースをコピーして試してみましたら、ちゃんと帰ってきました。
ただ私の作成したソースは未だ値が帰ってきません。
業務で使用しているdllに組み込んだので部分的にしかソース
の貼り付けが出来なかったのですが、他に原因があるのかも
知れません。
とりあえず、解決とさせてください。
お騒がせして申し訳ありませんでした。
ツイート | ![]() |