//我要做一个DLL,供其它语言使用!
//在从主调程序申请了内存后,把地址传递给DLL程序,发现被传递过去的Str的地址与主调中的Str地址不一致
//结果可想而知,提示指针操作无效!
//请问如何才能正确处理!
//很郁闷......
var
Str:PChar;
begin
GetMem(Str,255);//我已经在主调程序中把内存申请,便于在主调中释放
Showmessage(Inttostr(Integer(Str)));//申请的内存地址首址
TestFunc(Str);
FreeMem(Str,255);
end;//DLLfunction TestFunc(Str:PChar):boolean;
begin
Showmessage(Inttostr(Integer(Str)));//传递过去的首址,发现地址不一样
Str:='Hello';
end;
解决方案 »
- 中间层中如何填加多个Remote Data Module
- 图象识别的问题!大家都来帮帮忙!
- 请问在98下能否安装delphi7.0?谁有delphi5安装版,能否发一个给我?
- 如何取出DBGrid中小箭头所指示行的所有字段的内容?
- 怎么查询评分最高的前五名成员
- 帮忙呀!为什么我运行的时候界面还是原来的可以编辑的界面,不能不运行呀!!!
- 如何让Treeview不显示滚动条,进者有分!
- URW3010是什么错误呀?如何解决?
- 怎样用FileStream往文件结尾填充指定字节的空白?
- 想用SetLocalTime设置系统时间,将结构SYSTEMTIME中的wHour + 1,却见不到效果。请问应该怎么做?本人新手一个。
- DELPHI多层分布式开发,关于服务器端
- 两个表的联连,加求和,求解!!!
它的内存我没仔细研究过到底在哪分配,但只有2个可能,一个就是栈里,另外一个就是堆里。
如果是堆里那按照AnsiString里介绍,它的释放由引用计数决定(String为指针,且在这个指针前面有4个字节的引用计数和4个字节的字符串长度),如果是在栈里,那函数调用完毕就会被清栈。
再看dll里的这句代码Str:='Hello';
将一个指针指向了一个新的内存,所以带来的问题是,你原来分配的内存在这句代码后就已经没办法再释放了。
而这个指针重新指向的内存却已经不是你自己来管理的了 ,所以会带来的问题会是
255个字节内存别泄漏,并且FreeMem(Str,255);会报内存相关错。
你需要将这句代码改成。
Str:=StrPCopy(Str,'Hello');
如果改成Str:=StrPCopy(Str,'Hello'); 还有错误,那有可能是函数调用惯例问题。
//DLL
//我就是这样一个小程序,在主调函数中申请内存资源,并把首址传给DLL,让DLL把相应的字符串填写完毕后,我在主程序中读取,并释放资源!
//大家都是怎么写的啊,能否给个例程
function TestFunc(Str:PChar):boolean;
begin
Showmessage(Inttostr(Integer(Str)));//
Str:='Hello';//这样写会改变
end;
begin
Showmessage(Inttostr(Integer(Str)));//传递过去的首址,发现地址不一样(*如果发现这里不一样,则有可能两边取值的方式不一样,或者参数传递错误*)
Str:='Hello';(*这个则只修改了作为参数的副本(本地变量)的指向并不对调用者当中相应的作为参数的变量造成影响*)
end;
var
Str:PChar;
begin
GetMem(Str,255);//我已经在主调程序中把内存申请,便于在主调中释放
ZeroMemory(Str,255); //这里使用API (*注意:仅Win2k以上操作系统才有此API,在Delphi当中为兼容低版本系统自己做了实现*)
CopyMemory(Str,PChar('Test1'),5); //这里使用API (*注意:仅Win2k以上操作系统才有此API,在Delphi当中为兼容低版本系统自己做了实现*)
ShowMessage(str);
Showmessage(Inttostr(Integer(Str)));//申请的内存地址首址
TestFunc(Str);
ShowMessage(str);
FreeMem(Str,255);
end;测试一
function TestFunc(Str:PChar):boolean;
begin
Showmessage(Inttostr(Integer(Str)));//传递过去的首址,发现地址不一样
Str:='Hello';
end;测试二
function TestFunc(Str:PChar):boolean;
begin
Showmessage(Inttostr(Integer(Str)));//传递过去的首址,发现地址不一样
CopyMemory(Str,PChar('Hello'),5); //这里使用API (*注意:仅Win2k以上操作系统才有此API,在Delphi当中为兼容低版本系统自己做了实现*)
end;
Str:PChar;
Size: LongWord;
begin
Size := 255;
GetMem(Str,Size );//我已经在主调程序中把内存申请,便于在主调中释放
Showmessage(Inttostr(Integer(Str)));//申请的内存地址首址
TestFunc(Str,Size);
FreeMem(Str (*,255 此参数可以不需要,而且最好不需要,否则前面申请时大小的变化与这里不匹配会导致问题*));
end;
function TestFunc(Str:PChar; var Size: LongWord):boolean;
var
LocalString: String;
begin
Showmessage(Inttostr(Integer(Str)));//传递过去的首址,发现地址不一样
LocalString := 'Hello';
//Str:='Hello';
CopyMemory(Str,PChar(LocalString),Min(Size,Length(LocalString)) (*在size不足时,仅以Size为准,以防溢出 *));
end;
------------------------------------------------
换句话说 这个Str与调用者的Str的值是一致的,但是其内容地址是不一样的,实在理解不了!指向的地址一样,而其内的数据不一样???是不是DLL内的内存管理器又单独为其分配了一个空间啊
Str的内容,即变量本身,一个四字节数据