数组指针问题,看起来简单做起来复杂,大家帮忙啊! Delphi / Windows SDK/APIhttp://www.delphi2007.net/DelphiDB/html/delphi_20061219113016224.html
我首先做了一个DLL 名字是“mydll”
library MYDLL;
uses
sharemem,
SysUtils,
ExtCtrls,
StdCtrls;
type Tps = Record
sno: integer; //序列号
fjcode:string[200];//代号
End;
Tp=array of Tps;
PTp = ^TP;
{$R *.RES}
function Select(var PResult:PTp):integer; export; stdcall;
begin
try
new(PResult);
setlength(PResult^,2);
PResult^[0].sno:=1;
PResult^[0].fjcode:='大大';
PResult^[1].sno:=2;
PResult^[1].fjcode:='小小';
result:=1;
finally
dispose(PResult);
end;
end;
exports
Select;
begin
end.
然后我用DELPIH用以下程序调用
var
Form1: TForm1;
type
Tps = Record
sno: integer; //序列号
fjcode:pchar;//系列代号,如DBF
End;
Tp=array of Tps;
PTp = ^TP;
implementation
{$R *.DFM}
function Select(var PResult:PTp):integer; export; stdcall;
external 'mydll.dll';
procedure TForm1.Button1Click(Sender: TObject);
var presult:PTp;
i:integer;
begin
i:=Select(PResult);
showmessage(PResult^[0].fjcode);//为什么会在这行错误呢???
showmessage(PResult^[1].fjcode);
end;
现在的问题是我看了我的DLL应该是没有问题的!
为什么showmessage(PResult^[0].fjcode);显示不出‘大大’两个字,反而报错‘内存访问错误’!
我该如何查看调用了DLL后函数中输出值PResult的输出结果‘大大’这两个字呢?
帖子贴出来已经一个小时了,在线等了一个多小时了,好着急,高手帮忙啊!
http://community.csdn.net/Expert/topic/5238/5238067.xml?temp=.7243158
maozefa(阿发伯)兄弟,因为我传进去的数组开多大是事先不知道的,所以必须在DLL中去动态setlength,我该怎么写呢?
另外象您将的先开好数组然后进去DLL赋值,那我又该做什么修改才能得到我的‘大大’这个输出结果呢?希望您不吝赤教啊,我水平不太好,又被逼到这个地步了,希望能得到您的指导!!!
首先,修改结构:
Tps = packed Record
sno: integer; //序列号
fjcode:array[0..199] of char;
end;
其次,Dll中增加一函数,返回数组大小。应用程序中先调用该函数,然后分配内存。
用指针作为参数调用Dll的Select
procedure TForm1.Button1Click(Sender: TObject);
var
presult:Tps;
i, Count: integer;
begin
Count := GetSelectCount; //假设Dll增加的函数,返回数组个数。
SetLength(presult, Count);
i:=Select(@PResult);
showmessage(PResult^[0].fjcode);
showmessage(PResult^[1].fjcode);
end;
没有测试,共参考。
我按您的方法做了,就是先分配地址后调用DLL
可是按您的代码:
SetLength(presult, Count);//有错误,应该是SetLength(presult^, Count);//
i:=Select(@PResult);//这句执行的时候说实参和形参类型不一样的。
现在还没有完成调试,就是说还没有得到‘大大’两个字出来,兄弟帮忙啊。。。
type
Tps = packed Record
sno: integer; //序列号
fjcode:array[0..199] of char;
end;
PTp = ^Tps;
TpArray = array of Tps;
function Select(PResult:PTp):integer; export; stdcall;
begin
TpArray(PResult)[0].sno:=1;
TpArray(PResult)[0].fjcode:='大大';
TpArray(PResult)[1].sno:=2;
TpArray(PResult)[1].fjcode:='小小';
result:=1;
end;
function GetSelectCount: Integer; export; stdcall;
begin
Result := 2;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
presult:Ptp;
i, Count: integer;
begin
Count := GetSelectCount; //假设Dll增加的函数,返回数组个数。
GetMem(PResult, sizeof(Tps) * Count);
try
i:=Select(PResult);
showmessage(TpArray(PResult)[0].fjcode);
showmessage(TpArray(PResult)[1].fjcode);
finally
FreeMem(PResult, sizeof(Tps) * Count);
end;
end;
我已经全面测试,没问题的:
library Project2;
uses
SysUtils,
Classes;
type
Tps = packed Record
sno: integer; //序列号
fjcode:array[0..199] of char;
end;
PTp = ^Tps;
TpArray = array of Tps;
function Select(PResult:PTp):integer; export; stdcall;
begin
TpArray(PResult)[0].sno:=1;
TpArray(PResult)[0].fjcode:='大大';
TpArray(PResult)[1].sno:=2;
TpArray(PResult)[1].fjcode:='小小';
result:=1;
end;
function GetSelectCount: Integer; export; stdcall;
begin
Result := 2;
end;
{$R *.res}
exports
Select,
GetSelectCount;
begin
end.
type
Tps = packed Record
sno: integer; //序列号
fjcode:array[0..199] of char;
end;
PTp = ^Tps;
TpArray = array of Tps;
function GetSelectCount: Integer; stdcall; external 'Project2.dll';
function Select(PResult:PTp):integer; stdcall; external 'Project2.dll';
procedure TForm1.Button1Click(Sender: TObject);
var
presult:Ptp;
i, Count: integer;
begin
Count := GetSelectCount; //假设Dll增加的函数,返回数组个数。
GetMem(PResult, sizeof(Tps) * Count);
try
i:=Select(PResult);
showmessage(TpArray(PResult)[0].fjcode);
showmessage(TpArray(PResult)[1].fjcode);
finally
FreeMem(PResult, sizeof(Tps) * Count);
end;
end;
maozefa(阿发伯) 谢谢,按您的方法结果出来了!不过我想追问一个问题:
type
Tps = packed Record
sno: integer; //序列号
fjcode:array[0..199] of char;
end;
PTp = ^Tps;
TpArray = array of Tps;
按您的这种方法定义和使用dll(就是ARRAY OF ...)其他语言调用我DELPHI写的DLL的时候会不会问题呢?
谢谢您的回复,您就是我的恩人啊。。。
没问题的,其他语言,比如C/C++的指针可以直接用下标的。
另外,把Dll中的function Select(PResult:PTp):integer; export; stdcall;
改为function Select(var PResult:PTp):integer; export; stdcall;
就可直接用SetLength分配数组长度了
procedure TForm1.Button1Click(Sender: TObject);
var
presult: array of Tps;
i, Count: integer;
begin
Count := GetSelectCount; //假设Dll增加的函数,返回数组个数。
SetLength(presult, Count);
i:=Select(@PResult);
showmessage(PResult[0].fjcode);
showmessage(PResult[1].fjcode);
end;
但是,程序中的函数说明不要改。
还是function Select(PResult:PTp):integer; stdcall; external 'Project2.dll';
使用下面的定义,就是方便其他语言如c/c++定义结构的
Tps = packed Record
实在太感谢了,有好多东西我还要边看边理解的!感谢感谢感谢感谢感谢感谢感谢感谢感谢感谢感谢感谢感谢感谢感谢感谢感谢感谢