構造体にChar型で正しく格納するには?

解決


  2006-03-22 06:39:49  No: 20641

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しか戻ってきません。
正しく格納されてないからじゃないかと考えているのですが、
どこがおかしいのか分からず悩んでいます。

もしご存知の方がいらっしゃったらご教授頂けないでしょうか?


不明  2006-03-22 12:15:16  No: 20642

>といったやり方で,構造体をdllに送ってやってるのですが、
どういったやり方?dllに送っているというソースがないですよね

もっと詳しく(分かりやすく)説明していただけませんか?


  2006-03-22 17:09:02  No: 20643

申し訳ありません。

function du_SendMail        (var FNotes : TNotes): LongInt;stdcall;

dll側では同じ構造体を用意して上記のような関数を作成しているので
exe側で呼び出して使用しています。
dllのfunction内でFNotesのA,B,Cはshowmessageで表示出来たのですが
他の項目が空(?)なのでうまく格納されていないと思っているのです。


igy  2006-03-22 20:31:40  No: 20644

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;


  2006-03-23 08:15:54  No: 20645

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を呼び出すとちゃんと表示されます。


igy  2006-03-23 18:06:05  No: 20646

こちらで試したプログラムは以下のとおりです。

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.


ん?  2006-03-23 18:11:50  No: 20647

// 宣言部
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さん同様、変なデータになりません。
入力した内容が、そのまま受け渡しされています。


  2006-03-24 08:56:51  No: 20648

igyさん、ん?さん、ありがとうございます。

ソースをコピーして試してみましたら、ちゃんと帰ってきました。
ただ私の作成したソースは未だ値が帰ってきません。
業務で使用しているdllに組み込んだので部分的にしかソース
の貼り付けが出来なかったのですが、他に原因があるのかも
知れません。

とりあえず、解決とさせてください。

お騒がせして申し訳ありませんでした。


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

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






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