Dll的问题! (50分)

  • 主题发起人 主题发起人 zwjChina
  • 开始时间 开始时间
Z

zwjChina

Unregistered / Unconfirmed
GUEST, unregistred user!
以下是我写的一个函数,我把放在Dll中使用!
function ASTGetUser(index: Integer): Pchar; stdcall;
var
UserName: array[0..20] of char;
UserCount: Integer;
F: File;
TmpName: array[0..19] of char;
begin
UserCount := ASTUserCount;
Result := '';
if (index > 0) and (index <= UserCount) then
begin
AssignFile(F, ExtractFilePath(ASTModulePath) + 'UserList.Dat');
Reset(F, 1);
Seek(F, (index - 1) * 21);
BlockRead(F, UserName[0], 21);
CloseFile(F);
Move(UserName[1], TmpName[0], 20);
Result := TmpName;
end;
end;
注意最后两句:
Move(UserName[1], TmpName[0], 20);
Result := TmpName;

以上方法可行,可是我用其他方法都不能正确得到返回值,不知道为什么,希望高手解释一下!
例如我用:
Result := PChar(@UserName[1])
不行

声明一个 Tmp: PChar;
Tmp := PChar(@UserName[1]);
Result := Tmp
也不行

我不明白Result 到底是怎么样传递出去的!按道理应该就是一个指针呀!
除了我最开始列的方法外,还有正确方法吗?
 
Result := @TmpName;
or
Result := @TmpName[0];

 
你说的和我列举的方法很象!
你能说说原因吗?
 
BeginDelphi, 你的方法我测试了,不行!

有高手能帮帮我吗?
 
这样返回应该会有问题:
最好是在参数列表中返回,
function ASTGetUser(index: Integer; user:Pchar): Word ; stdcall;
具体为什么,我也不太清楚,反正我用了总是出错!(我总觉得Result并没有真正的分配空间!)
API,也很少用这种返回方式的!
 
但是奇怪的是用字符数组可以啊!
如上面我列举的方法
 
试试这样吧,看行不
Result := pchar(UserName);
 
也许Result只返回字针吧!
Result := TmpName,将TmpName.指针赋给他了吧!
tmpname是有大小的吧!
也许你申明一个PChar给其分配空间,然后不释放这个空间也行!
----------------------
具体我也不明了,正好我也要学习学习,请多指教!
 
mk1024,你的方法是可行的!
但是,是这样的,我要把UserName从第2个字符后的字符串返回!
 
我改了改代码
加入了以下代码
var
P: Pchar
begin
......
New(p);
Move(UserName[1], p^, 20);
Result := P;
end;
这样的确成功了,所以返回的的确是指针!
但是这样就引出了一个问题!New(p)怎么释放资源呢?显然在过程内Dispose(p)是
不对的!
 
所以,我认为用参数来返回比较正确;
其实你的数组也同样没有释放空间;它和PChar一样;只是已经声明好了!
这返回的PChar能有值,代表其指向一个数据区,那这个数据区你如何释放呢?
你的程序中并没有释放啊!

这种调用应该在调用之前分配空间,然后再释放空间,这样才能保证无误,否则内存总是
有些问题的!
 
那个数组是过程内的局部变量,为什么没有释放?
按一般的说明是应该有释放的啊!

而对于PChar,也是局部变量,过程退出后只释放保存pchar指针的值的空间;
而不释放指针指向的地址分配的空间。

这是我的理解!可能理解有误!
 
是啊,按照一般的说明就应该释放了,那么Result的返回值应该为空是不是?
那么PChar类型为什么还有返回值,除非Result建立了另一份拷贝值!

 
恩,你说的也是个问题!
所以很希望有高手来说明一下啊!

另,你知道怎给这个帖子加分吗?
 
to 冷叶风
我QQ:21771272
如果愿意你可以加我!:)
 
接受答案了.
 
上次看错题咯。对不起哦!
先看看下面两段程序:
program Project2;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
User:array[0..20]of Char;
function TestPChar:PChar;stdcall;
begin
FillChar(User,21,#0);
StrPCopy(@User[0],'abcdefghijklmnopqrst');
Writeln(PChar(@User[1]));
Result := @User[1];
end;
begin
Write(TestPChar);
Readln;
end.

program Project2;
{$APPTYPE CONSOLE}
uses
SysUtils;
var
function TestPChar:PChar;stdcall;
var
User:array[0..20]of Char;
begin
FillChar(User,21,#0);
StrPCopy(@User[0],'abcdefghijklmnopqrst');
Writeln(PChar(@User[1]));
Result := @User[1];
end;
begin
Write(TestPChar);
Readln;
end.

有什么不同?初看好像没有什么不一样,但运行起来的效果是完全不一样的。
你的程序用的是局部变量,函数退出时会自动收回。所以你的指针是对的,但内容不对。
 
后退
顶部