......
procedure Tfrm_form1.btn1Click(Sender: TObject);
var p1,p2:pchar;
tmp,r1:real;
begin
tmp:=getkk(p1,p2,r1);
if tmp=0 then showmessage('成功 '+p1+' '+p2+' '+floattostr(r1));
end;
调用别人的DLL,调用前1、2次总是很正常,3次以后就会巨慢无比,目前严重怀疑是PCHAR的内存分配和释放的问题
几个PCHAR变量都是我的程序定义的(参数是返回值参数),在无法知道DLL里面做了些什么操作的情况下,我如何能确保PCHAR能够正确的分配和释放内存???
若直接使用GetMem和FreeMem,在FreeMem时会出错。。求教求教。。。。。。。
其实还是上个帖子的问题:http://topic.csdn.net/u/20110714/11/330f9627-85f0-4a01-bf06-7443b5708125.html?40341
这次换个问法,,继续求救。。。
36 个解决方案
#1
找个memproof检查下代码有没有资源泄漏……
#2
应该和dll内部处理有关系,每个pchar多大的空间,stdcall调用应该是由被调的函数清除堆栈,不知你的getmem,freemem怎么用的
#3
你可以先确认一下,程序是否有内存泄漏,在你的项目文件中,加上ReportMemoryLeaksOnShutdown := True;一句,在退出程序时,若有泄漏,就会有报告。
#4
回1,3楼,因为DLL内包含专网通讯,本地没法调试,只有客户处的一台电脑能用,那电脑还忙的不行,每次只能弄好程序上去搞几分钟就得下,很难查啊
如果说就是确定有内存泄露了,该怎么改啊?
回2楼,俺试过这么写
begin
GetMem(p1,20);
GetMem(p2,1);
tmp:=getkk(p1,p2,r1);
if tmp=0 then showmessage('成功 '+p1+' '+p2+' '+floattostr(r1));
FreeMem(p1);
FreeMem(p2);
end;
这样在FreeMem时会报错,而且速度一样慢,去掉FreeMem不报错,不过也没用
俺还试过给10倍大小空间,如GetMem(p1,200)...,还是没用,,=。=
如果说就是确定有内存泄露了,该怎么改啊?
回2楼,俺试过这么写
begin
GetMem(p1,20);
GetMem(p2,1);
tmp:=getkk(p1,p2,r1);
if tmp=0 then showmessage('成功 '+p1+' '+p2+' '+floattostr(r1));
FreeMem(p1);
FreeMem(p2);
end;
这样在FreeMem时会报错,而且速度一样慢,去掉FreeMem不报错,不过也没用
俺还试过给10倍大小空间,如GetMem(p1,200)...,还是没用,,=。=
#5
俺现在考虑2种情况,,
1是在我的程序里能控制最好,在调用前后分配和释放好PCHAR内存,但是不知道该怎么做。。
2是实在不行,要改DLL的话,就得有具体的语句,,比如说告诉DLL方你把这句语句加在某某地方试试,,之类的,要叫DLL方去查问题所在是行不通的,如前一个帖子所说,因为他们提供的例程有完全相同的调用,速度就是正常的,,,唉,,俺头大如斗。。。。。
1是在我的程序里能控制最好,在调用前后分配和释放好PCHAR内存,但是不知道该怎么做。。
2是实在不行,要改DLL的话,就得有具体的语句,,比如说告诉DLL方你把这句语句加在某某地方试试,,之类的,要叫DLL方去查问题所在是行不通的,如前一个帖子所说,因为他们提供的例程有完全相同的调用,速度就是正常的,,,唉,,俺头大如斗。。。。。
#6
顶下。。。
#7
用Numaga BoundsChecker,Purify,或是PurifyPlus工具检查一下
#8
我是看不出问题,能否把他官方提供的VC,VB之类的函数原型声明拿来看看
#9
最好能把函数原型拿出来看看,说不定问题很简单
原来弄过一个DLL(VC写的),调试了一上午,头都大了,最后找到问题是传进去的参数初始化的问题。
原来弄过一个DLL(VC写的),调试了一上午,头都大了,最后找到问题是传进去的参数初始化的问题。
#10
Function getkk(var p1,p2:pchar; var r1:real):real;stdcall;external 'phfhud.DLL' name 'getkk';
从这个函数来看,内存是在库里面申请的,可以查看该库是否有释放函数,
从这个函数来看,内存是在库里面申请的,可以查看该库是否有释放函数,
#11
phfhud.DLL会不会还引用了别的什么文件。
#12
Function getkk(var p1,p2:pchar; var r1:real):
这个声明有问题: 不必加入:var
getkk(p1,p2:pchar; var r1:real): 这样就可以了
这个声明有问题: 不必加入:var
getkk(p1,p2:pchar; var r1:real): 这样就可以了
#13
procedure Tfrm_form1.btn1Click(Sender: TObject);
var p1,p2:pchar;
tmp,r1:real;
begin
tmp:=getkk(p1,p2,r1);
if tmp=0 then showmessage('成功 '+p1+' '+p2+' '+floattostr(r1));
end;
调用别人的DLL,调用前1、2次总是很正常,3次以后就会巨慢无比
既然这个正常,肯定应该是var
#14
var pchar传入dll时是指针的指针
如果其中有FreeMem的话,FreeMem是根据变量所引用的指针释放内存,并将内存归还给堆。如果指针不是指向堆中的内存地址,将发生一个运行时错误
如果其中有FreeMem的话,FreeMem是根据变量所引用的指针释放内存,并将内存归还给堆。如果指针不是指向堆中的内存地址,将发生一个运行时错误
#15
可能是没有正常释放DLL文件
#16
getkk(var p1,p2:pchar; var r1:real):
对于传PChar的函数,通常做法都是在外部分配足够大的空间,然后再传入,而不是在动态库里面分配,对于内存分配如果跨语言,一定要保证,谁申请谁释放。
对于传PChar的函数,通常做法都是在外部分配足够大的空间,然后再传入,而不是在动态库里面分配,对于内存分配如果跨语言,一定要保证,谁申请谁释放。
#17
回复于:2011-07-19 11:21:19引用 12 楼 xhz2000 的回复:
Function getkk(var p1,p2:pchar; var r1:real):
这个声明有问题: 不必加入:var
getkk(p1,p2:pchar; var r1:real): 这样就可以了
procedure Tfrm_form1.btn1Click(Sender: TObject);
var p1,p2:pchar;
tmp,r1:real;
begin
tmp:=getkk(p1,p2,r1);
if tmp=0 then showmessage('成功 '+p1+' '+p2+' '+floattostr(r1));
end;
调用别人的DLL,调用前1、2次总是很正常,3次以后就会巨慢无比
既然这个正常,肯定应该是var
///////////////////////////////
to: kiboisme
请好好看楼主的回帖,由于getmem 后调用freemem 出问题,就是定义为var 所造成的;
在从常识来说 var 就是传入引用,PChar 本来就是指针,你说还要var 吗??
Function getkk(var p1,p2:pchar; var r1:real):
这个声明有问题: 不必加入:var
getkk(p1,p2:pchar; var r1:real): 这样就可以了
procedure Tfrm_form1.btn1Click(Sender: TObject);
var p1,p2:pchar;
tmp,r1:real;
begin
tmp:=getkk(p1,p2,r1);
if tmp=0 then showmessage('成功 '+p1+' '+p2+' '+floattostr(r1));
end;
调用别人的DLL,调用前1、2次总是很正常,3次以后就会巨慢无比
既然这个正常,肯定应该是var
///////////////////////////////
to: kiboisme
请好好看楼主的回帖,由于getmem 后调用freemem 出问题,就是定义为var 所造成的;
在从常识来说 var 就是传入引用,PChar 本来就是指针,你说还要var 吗??
#18
可这个PChar也可以如下:
Application.MessageBox(PChar(Errorstr),'错误信息:',MB_ICONERROR);
#19
可这个PChar也可以如下:
Application.MessageBox(PChar(Errorstr),'错误信息:',MB_ICONERROR);
这个跟楼主的使用时两回事好不好!
Application.MessageBox(PChar(Errorstr),'错误信息:',MB_ICONERROR);
这个跟楼主的使用时两回事好不好!
#20
memproof 是什么
#21
procedure Tfrm_form1.btn1Click(Sender: TObject);
var p1,p2:pchar;
tmp,r1:real;
begin
tmp:=getkk(p1,p2,r1);
if tmp=0 then showmessage('成功 '+p1+' '+p2+' '+floattostr(r1));
end;
我再说一次,既然这样能运行成功一次,那怕是一次,肯定是在 DLL中申请的,和FreeMem,GetMem完全没关系
#22
当前了所谓运行成功,肯定是有正常返回值的情况下才叫成功.否则在对这个"成功"的理解就有偏差的话,就没必要讨论了.
如果是我认为的成功的情况下(参数在调用后后返回值),那就肯定应该是var xx : PChar
如果是我认为的成功的情况下(参数在调用后后返回值),那就肯定应该是var xx : PChar
#23
21L的,我想问一句pchar申请后不释放1次会出问题么,2次会出问题么?第几次会出问题?程序不会变慢么?
LZ也说了,错误消息出在freemem上,而不是第一次运行上
程序会越来越慢的一个可能性原因就是内存释放
从代码看传入的是指针的指针,那么如果dll内对指针进行了分配操作,调用函数按照标准pchar的释放方法去释放该指针,就可能出错,我在14L已经说了“如果其中有FreeMem的话,FreeMem是根据变量所引用的指针释放内存,并将内存归还给堆。如果指针不是指向堆中的内存地址,将发生一个运行时错误”
LZ也说了,错误消息出在freemem上,而不是第一次运行上
程序会越来越慢的一个可能性原因就是内存释放
从代码看传入的是指针的指针,那么如果dll内对指针进行了分配操作,调用函数按照标准pchar的释放方法去释放该指针,就可能出错,我在14L已经说了“如果其中有FreeMem的话,FreeMem是根据变量所引用的指针释放内存,并将内存归还给堆。如果指针不是指向堆中的内存地址,将发生一个运行时错误”
#24
我都不知道怎么说了
既然是别人写的DLL,别人为什么不可以导出一个Closexxx,Freexxx的函数给你使用?
执行Socket时,系统同样会申请内存来存放上下文,最后还不是需要用CloseSocket来释放,我不知道这个别人写的DLL,要求传入var P : PChar有什么错.如果这个DLL真的是要求传入var P : PChar的话,那你对这个P进行FreeMem当然要出错了.
既然是别人写的DLL,别人为什么不可以导出一个Closexxx,Freexxx的函数给你使用?
执行Socket时,系统同样会申请内存来存放上下文,最后还不是需要用CloseSocket来释放,我不知道这个别人写的DLL,要求传入var P : PChar有什么错.如果这个DLL真的是要求传入var P : PChar的话,那你对这个P进行FreeMem当然要出错了.
#25
我只是就事论事在讨论程序变慢的可能性,并没有去讨论var P : PChar有什么错
我刚才已经说了,lz说调用freemem会出错,可能性只有两个
1 该内存已经被释放
2 该指针没有指向堆内存地址
dll已经被封装好了,代码无从而之,那么也许作者发布了Closexxx,Freexxx的函数,在作者的程序中执行没有问题
但是我从LZ提供的代码中并未发现,Closexxx,Freexxx的函数不是么?
那我怀疑var P : PChar这句可能产生错误,又错在哪里呢?
我刚才已经说了,lz说调用freemem会出错,可能性只有两个
1 该内存已经被释放
2 该指针没有指向堆内存地址
dll已经被封装好了,代码无从而之,那么也许作者发布了Closexxx,Freexxx的函数,在作者的程序中执行没有问题
但是我从LZ提供的代码中并未发现,Closexxx,Freexxx的函数不是么?
那我怀疑var P : PChar这句可能产生错误,又错在哪里呢?
#26
procedure Tfrm_form1.btn1Click(Sender: TObject);
var p1,p2:pchar;
tmp,r1:real;
begin
tmp:=getkk(p1,p2,r1);
if tmp=0 then showmessage('成功 '+p1+' '+p2+' '+floattostr(r1));
end;
如果这段代码执行没有出错,而且p1,p2有值的情况下,那参数肯定是var xx : PChar;
var p1,p2:pchar;
tmp,r1:real;
begin
tmp:=getkk(p1,p2,r1);
if tmp=0 then showmessage('成功 '+p1+' '+p2+' '+floattostr(r1));
end;
如果这段代码执行没有出错,而且p1,p2有值的情况下,那参数肯定是var xx : PChar;
#27
kiboisme
(蓝色光芒)
说的是我的看法。 kiboisme 你也是猜测而已。不是说在DLL内部不能分配内存。
别人为什么不可以导出一个Closexxx,Freexxx的函数给你使用,这个是可以的
但是楼主根本没有说起清楚。 而且也没有见到楼主调用释放内存函数。 只见他有
getmem 和 freemem ; 所以结论是在调用者分配好内存,然后调用者释放内存
比较接近楼主的用法!
跟你 funxu (可以人笨但不能手懒) 没关系的
(蓝色光芒)
说的是我的看法。 kiboisme 你也是猜测而已。不是说在DLL内部不能分配内存。
别人为什么不可以导出一个Closexxx,Freexxx的函数给你使用,这个是可以的
但是楼主根本没有说起清楚。 而且也没有见到楼主调用释放内存函数。 只见他有
getmem 和 freemem ; 所以结论是在调用者分配好内存,然后调用者释放内存
比较接近楼主的用法!
跟你 funxu (可以人笨但不能手懒) 没关系的
#28
对,楼主的实际情况没说清楚,所以只有猜.尽量帮楼主解决问题,我在10楼就说了,看dll其他导出函数.我看他那代码能运行,而且估计也有返回值,肯定在dll中申请的,对dll中申请的内存释放,如果没有ShareMem支撑,肯定要出错
#29
【【【俺是LZ】】】
非常非常谢谢大家的回帖。。。今天俺又折腾了一天,,,郁闷的不行
可能俺表达能力不好,俺再说明一下
1、DLL的说明档是说的DLL会分配内存,调用方无需处理,他给出的例程调用方法和DLL加载都和我的是一样的,但是别对DLL内的处理模式抱太大的信心。。。
2、第一次调用总是正常的,第二最多第三次,就会出问题,所谓出问题就是速度巨慢,正常5秒慢的5分钟,谁也受不了。。。但是无论速度快慢,返回的结果都是正确无误的
3、DLL没有提供任何Closexxx,Freexxx之类的函数可用
4、GETMEM和FREEMEM是俺在尝试加上去是否可行,结果是GETMEM加上去没有效果,同时加上FREEMEM则发生异常
5、今天下午开始尝试动态加载DLL的方式,结果奇怪的事发生了,开始是一调用DLL直接抛出内存异常,后来我加上了GETMEM,居然就不报错了。。。汗,,速度问题还没来得及试,客户下班了,只好明天再说(DLL内含专网通讯,只有客户处能测试)
非常非常谢谢大家的回帖。。。今天俺又折腾了一天,,,郁闷的不行
可能俺表达能力不好,俺再说明一下
1、DLL的说明档是说的DLL会分配内存,调用方无需处理,他给出的例程调用方法和DLL加载都和我的是一样的,但是别对DLL内的处理模式抱太大的信心。。。
2、第一次调用总是正常的,第二最多第三次,就会出问题,所谓出问题就是速度巨慢,正常5秒慢的5分钟,谁也受不了。。。但是无论速度快慢,返回的结果都是正确无误的
3、DLL没有提供任何Closexxx,Freexxx之类的函数可用
4、GETMEM和FREEMEM是俺在尝试加上去是否可行,结果是GETMEM加上去没有效果,同时加上FREEMEM则发生异常
5、今天下午开始尝试动态加载DLL的方式,结果奇怪的事发生了,开始是一调用DLL直接抛出内存异常,后来我加上了GETMEM,居然就不报错了。。。汗,,速度问题还没来得及试,客户下班了,只好明天再说(DLL内含专网通讯,只有客户处能测试)
#30
给出函数的原型看看,要文档里面(应该是C/C++写的吧?)不是你在D调用的那个
#31
还有,你是用Delphi几?C里面的原型中的char *char,对应的是PAnsiChar,Delphi几开始默认的PChar是PWideChar了,你看看是不是这问题
#32
这个DLL也是DELPHI写的,版本不清楚。。。。俺用的是D6
#33
强烈要求给出文档说明,函数原型等。
#34
那就动态加载嘛,每次操作都是一次新的
#35
我觉得这个应该是dll的问题 想想看就算你在内存中创建3个pchan不释放 也不会造成你所说的那种卡的问题 我觉得应该是dll里面有其他的消耗内存的东西
#36
你作为一个星星还真牛X,什么叫没有ShareMem支撑就出错?我只看到PCHAR,没看到String;
另外,var P: Pchar,一看这样的参数,我就能猜到DLL的作者是什么样的想法.因为前不久我就遇到一个相同的做了N年DELPHI的人用相同的思路,让我纠结了很久,但到底是对方改正了,因为用了不久就出问题了
说正经的,楼主说用上GetMem和FreeMem,在FreeMem的时候会报错,那是因为DLL的作者在那个函数的内部改变了p1,p2的值,也就是说,你在FreeMem的时候已经不是你当初GetMem的值了,猜出这一点是根据你说在FreeMem的时候报错,你不信你就调试一下,看一下你调用前和调用后的时候P1,P2的值是不是一样.
如果是这样的话,有三种情况:
1: 即它也提供了一个释放的函数,调用完之后,用这个释放的函数去释放,否则就会有内存泄露.
2: P1,P2返回的是DLL中的全局变量,不需要额外释放.如果是这样话,你可以直接传进两个未初始化的指针进去,不也不去释放
2: P1,P2返回的是局部变量,即是堆栈中分配的内存,基本上,就只能自求多福了.这样的问题基本上是给你的DEMO表面没问题,但是你在用的时候随机性的出问题
说了一大堆,和你的程序运行快慢没多大关系,按道理来说,即使是内存有泄露,也不应该第三次就影响速度.毕竟还不知道代码,当前的问题,就是找出这个函数到底是怎么个意思
#1
找个memproof检查下代码有没有资源泄漏……
#2
应该和dll内部处理有关系,每个pchar多大的空间,stdcall调用应该是由被调的函数清除堆栈,不知你的getmem,freemem怎么用的
#3
你可以先确认一下,程序是否有内存泄漏,在你的项目文件中,加上ReportMemoryLeaksOnShutdown := True;一句,在退出程序时,若有泄漏,就会有报告。
#4
回1,3楼,因为DLL内包含专网通讯,本地没法调试,只有客户处的一台电脑能用,那电脑还忙的不行,每次只能弄好程序上去搞几分钟就得下,很难查啊
如果说就是确定有内存泄露了,该怎么改啊?
回2楼,俺试过这么写
begin
GetMem(p1,20);
GetMem(p2,1);
tmp:=getkk(p1,p2,r1);
if tmp=0 then showmessage('成功 '+p1+' '+p2+' '+floattostr(r1));
FreeMem(p1);
FreeMem(p2);
end;
这样在FreeMem时会报错,而且速度一样慢,去掉FreeMem不报错,不过也没用
俺还试过给10倍大小空间,如GetMem(p1,200)...,还是没用,,=。=
如果说就是确定有内存泄露了,该怎么改啊?
回2楼,俺试过这么写
begin
GetMem(p1,20);
GetMem(p2,1);
tmp:=getkk(p1,p2,r1);
if tmp=0 then showmessage('成功 '+p1+' '+p2+' '+floattostr(r1));
FreeMem(p1);
FreeMem(p2);
end;
这样在FreeMem时会报错,而且速度一样慢,去掉FreeMem不报错,不过也没用
俺还试过给10倍大小空间,如GetMem(p1,200)...,还是没用,,=。=
#5
俺现在考虑2种情况,,
1是在我的程序里能控制最好,在调用前后分配和释放好PCHAR内存,但是不知道该怎么做。。
2是实在不行,要改DLL的话,就得有具体的语句,,比如说告诉DLL方你把这句语句加在某某地方试试,,之类的,要叫DLL方去查问题所在是行不通的,如前一个帖子所说,因为他们提供的例程有完全相同的调用,速度就是正常的,,,唉,,俺头大如斗。。。。。
1是在我的程序里能控制最好,在调用前后分配和释放好PCHAR内存,但是不知道该怎么做。。
2是实在不行,要改DLL的话,就得有具体的语句,,比如说告诉DLL方你把这句语句加在某某地方试试,,之类的,要叫DLL方去查问题所在是行不通的,如前一个帖子所说,因为他们提供的例程有完全相同的调用,速度就是正常的,,,唉,,俺头大如斗。。。。。
#6
顶下。。。
#7
用Numaga BoundsChecker,Purify,或是PurifyPlus工具检查一下
#8
我是看不出问题,能否把他官方提供的VC,VB之类的函数原型声明拿来看看
#9
最好能把函数原型拿出来看看,说不定问题很简单
原来弄过一个DLL(VC写的),调试了一上午,头都大了,最后找到问题是传进去的参数初始化的问题。
原来弄过一个DLL(VC写的),调试了一上午,头都大了,最后找到问题是传进去的参数初始化的问题。
#10
Function getkk(var p1,p2:pchar; var r1:real):real;stdcall;external 'phfhud.DLL' name 'getkk';
从这个函数来看,内存是在库里面申请的,可以查看该库是否有释放函数,
从这个函数来看,内存是在库里面申请的,可以查看该库是否有释放函数,
#11
phfhud.DLL会不会还引用了别的什么文件。
#12
Function getkk(var p1,p2:pchar; var r1:real):
这个声明有问题: 不必加入:var
getkk(p1,p2:pchar; var r1:real): 这样就可以了
这个声明有问题: 不必加入:var
getkk(p1,p2:pchar; var r1:real): 这样就可以了
#13
procedure Tfrm_form1.btn1Click(Sender: TObject);
var p1,p2:pchar;
tmp,r1:real;
begin
tmp:=getkk(p1,p2,r1);
if tmp=0 then showmessage('成功 '+p1+' '+p2+' '+floattostr(r1));
end;
调用别人的DLL,调用前1、2次总是很正常,3次以后就会巨慢无比
既然这个正常,肯定应该是var
#14
var pchar传入dll时是指针的指针
如果其中有FreeMem的话,FreeMem是根据变量所引用的指针释放内存,并将内存归还给堆。如果指针不是指向堆中的内存地址,将发生一个运行时错误
如果其中有FreeMem的话,FreeMem是根据变量所引用的指针释放内存,并将内存归还给堆。如果指针不是指向堆中的内存地址,将发生一个运行时错误
#15
可能是没有正常释放DLL文件
#16
getkk(var p1,p2:pchar; var r1:real):
对于传PChar的函数,通常做法都是在外部分配足够大的空间,然后再传入,而不是在动态库里面分配,对于内存分配如果跨语言,一定要保证,谁申请谁释放。
对于传PChar的函数,通常做法都是在外部分配足够大的空间,然后再传入,而不是在动态库里面分配,对于内存分配如果跨语言,一定要保证,谁申请谁释放。
#17
回复于:2011-07-19 11:21:19引用 12 楼 xhz2000 的回复:
Function getkk(var p1,p2:pchar; var r1:real):
这个声明有问题: 不必加入:var
getkk(p1,p2:pchar; var r1:real): 这样就可以了
procedure Tfrm_form1.btn1Click(Sender: TObject);
var p1,p2:pchar;
tmp,r1:real;
begin
tmp:=getkk(p1,p2,r1);
if tmp=0 then showmessage('成功 '+p1+' '+p2+' '+floattostr(r1));
end;
调用别人的DLL,调用前1、2次总是很正常,3次以后就会巨慢无比
既然这个正常,肯定应该是var
///////////////////////////////
to: kiboisme
请好好看楼主的回帖,由于getmem 后调用freemem 出问题,就是定义为var 所造成的;
在从常识来说 var 就是传入引用,PChar 本来就是指针,你说还要var 吗??
Function getkk(var p1,p2:pchar; var r1:real):
这个声明有问题: 不必加入:var
getkk(p1,p2:pchar; var r1:real): 这样就可以了
procedure Tfrm_form1.btn1Click(Sender: TObject);
var p1,p2:pchar;
tmp,r1:real;
begin
tmp:=getkk(p1,p2,r1);
if tmp=0 then showmessage('成功 '+p1+' '+p2+' '+floattostr(r1));
end;
调用别人的DLL,调用前1、2次总是很正常,3次以后就会巨慢无比
既然这个正常,肯定应该是var
///////////////////////////////
to: kiboisme
请好好看楼主的回帖,由于getmem 后调用freemem 出问题,就是定义为var 所造成的;
在从常识来说 var 就是传入引用,PChar 本来就是指针,你说还要var 吗??
#18
可这个PChar也可以如下:
Application.MessageBox(PChar(Errorstr),'错误信息:',MB_ICONERROR);
#19
可这个PChar也可以如下:
Application.MessageBox(PChar(Errorstr),'错误信息:',MB_ICONERROR);
这个跟楼主的使用时两回事好不好!
Application.MessageBox(PChar(Errorstr),'错误信息:',MB_ICONERROR);
这个跟楼主的使用时两回事好不好!
#20
memproof 是什么
#21
procedure Tfrm_form1.btn1Click(Sender: TObject);
var p1,p2:pchar;
tmp,r1:real;
begin
tmp:=getkk(p1,p2,r1);
if tmp=0 then showmessage('成功 '+p1+' '+p2+' '+floattostr(r1));
end;
我再说一次,既然这样能运行成功一次,那怕是一次,肯定是在 DLL中申请的,和FreeMem,GetMem完全没关系
#22
当前了所谓运行成功,肯定是有正常返回值的情况下才叫成功.否则在对这个"成功"的理解就有偏差的话,就没必要讨论了.
如果是我认为的成功的情况下(参数在调用后后返回值),那就肯定应该是var xx : PChar
如果是我认为的成功的情况下(参数在调用后后返回值),那就肯定应该是var xx : PChar
#23
21L的,我想问一句pchar申请后不释放1次会出问题么,2次会出问题么?第几次会出问题?程序不会变慢么?
LZ也说了,错误消息出在freemem上,而不是第一次运行上
程序会越来越慢的一个可能性原因就是内存释放
从代码看传入的是指针的指针,那么如果dll内对指针进行了分配操作,调用函数按照标准pchar的释放方法去释放该指针,就可能出错,我在14L已经说了“如果其中有FreeMem的话,FreeMem是根据变量所引用的指针释放内存,并将内存归还给堆。如果指针不是指向堆中的内存地址,将发生一个运行时错误”
LZ也说了,错误消息出在freemem上,而不是第一次运行上
程序会越来越慢的一个可能性原因就是内存释放
从代码看传入的是指针的指针,那么如果dll内对指针进行了分配操作,调用函数按照标准pchar的释放方法去释放该指针,就可能出错,我在14L已经说了“如果其中有FreeMem的话,FreeMem是根据变量所引用的指针释放内存,并将内存归还给堆。如果指针不是指向堆中的内存地址,将发生一个运行时错误”
#24
我都不知道怎么说了
既然是别人写的DLL,别人为什么不可以导出一个Closexxx,Freexxx的函数给你使用?
执行Socket时,系统同样会申请内存来存放上下文,最后还不是需要用CloseSocket来释放,我不知道这个别人写的DLL,要求传入var P : PChar有什么错.如果这个DLL真的是要求传入var P : PChar的话,那你对这个P进行FreeMem当然要出错了.
既然是别人写的DLL,别人为什么不可以导出一个Closexxx,Freexxx的函数给你使用?
执行Socket时,系统同样会申请内存来存放上下文,最后还不是需要用CloseSocket来释放,我不知道这个别人写的DLL,要求传入var P : PChar有什么错.如果这个DLL真的是要求传入var P : PChar的话,那你对这个P进行FreeMem当然要出错了.
#25
我只是就事论事在讨论程序变慢的可能性,并没有去讨论var P : PChar有什么错
我刚才已经说了,lz说调用freemem会出错,可能性只有两个
1 该内存已经被释放
2 该指针没有指向堆内存地址
dll已经被封装好了,代码无从而之,那么也许作者发布了Closexxx,Freexxx的函数,在作者的程序中执行没有问题
但是我从LZ提供的代码中并未发现,Closexxx,Freexxx的函数不是么?
那我怀疑var P : PChar这句可能产生错误,又错在哪里呢?
我刚才已经说了,lz说调用freemem会出错,可能性只有两个
1 该内存已经被释放
2 该指针没有指向堆内存地址
dll已经被封装好了,代码无从而之,那么也许作者发布了Closexxx,Freexxx的函数,在作者的程序中执行没有问题
但是我从LZ提供的代码中并未发现,Closexxx,Freexxx的函数不是么?
那我怀疑var P : PChar这句可能产生错误,又错在哪里呢?
#26
procedure Tfrm_form1.btn1Click(Sender: TObject);
var p1,p2:pchar;
tmp,r1:real;
begin
tmp:=getkk(p1,p2,r1);
if tmp=0 then showmessage('成功 '+p1+' '+p2+' '+floattostr(r1));
end;
如果这段代码执行没有出错,而且p1,p2有值的情况下,那参数肯定是var xx : PChar;
var p1,p2:pchar;
tmp,r1:real;
begin
tmp:=getkk(p1,p2,r1);
if tmp=0 then showmessage('成功 '+p1+' '+p2+' '+floattostr(r1));
end;
如果这段代码执行没有出错,而且p1,p2有值的情况下,那参数肯定是var xx : PChar;
#27
kiboisme
(蓝色光芒)
说的是我的看法。 kiboisme 你也是猜测而已。不是说在DLL内部不能分配内存。
别人为什么不可以导出一个Closexxx,Freexxx的函数给你使用,这个是可以的
但是楼主根本没有说起清楚。 而且也没有见到楼主调用释放内存函数。 只见他有
getmem 和 freemem ; 所以结论是在调用者分配好内存,然后调用者释放内存
比较接近楼主的用法!
跟你 funxu (可以人笨但不能手懒) 没关系的
(蓝色光芒)
说的是我的看法。 kiboisme 你也是猜测而已。不是说在DLL内部不能分配内存。
别人为什么不可以导出一个Closexxx,Freexxx的函数给你使用,这个是可以的
但是楼主根本没有说起清楚。 而且也没有见到楼主调用释放内存函数。 只见他有
getmem 和 freemem ; 所以结论是在调用者分配好内存,然后调用者释放内存
比较接近楼主的用法!
跟你 funxu (可以人笨但不能手懒) 没关系的
#28
对,楼主的实际情况没说清楚,所以只有猜.尽量帮楼主解决问题,我在10楼就说了,看dll其他导出函数.我看他那代码能运行,而且估计也有返回值,肯定在dll中申请的,对dll中申请的内存释放,如果没有ShareMem支撑,肯定要出错
#29
【【【俺是LZ】】】
非常非常谢谢大家的回帖。。。今天俺又折腾了一天,,,郁闷的不行
可能俺表达能力不好,俺再说明一下
1、DLL的说明档是说的DLL会分配内存,调用方无需处理,他给出的例程调用方法和DLL加载都和我的是一样的,但是别对DLL内的处理模式抱太大的信心。。。
2、第一次调用总是正常的,第二最多第三次,就会出问题,所谓出问题就是速度巨慢,正常5秒慢的5分钟,谁也受不了。。。但是无论速度快慢,返回的结果都是正确无误的
3、DLL没有提供任何Closexxx,Freexxx之类的函数可用
4、GETMEM和FREEMEM是俺在尝试加上去是否可行,结果是GETMEM加上去没有效果,同时加上FREEMEM则发生异常
5、今天下午开始尝试动态加载DLL的方式,结果奇怪的事发生了,开始是一调用DLL直接抛出内存异常,后来我加上了GETMEM,居然就不报错了。。。汗,,速度问题还没来得及试,客户下班了,只好明天再说(DLL内含专网通讯,只有客户处能测试)
非常非常谢谢大家的回帖。。。今天俺又折腾了一天,,,郁闷的不行
可能俺表达能力不好,俺再说明一下
1、DLL的说明档是说的DLL会分配内存,调用方无需处理,他给出的例程调用方法和DLL加载都和我的是一样的,但是别对DLL内的处理模式抱太大的信心。。。
2、第一次调用总是正常的,第二最多第三次,就会出问题,所谓出问题就是速度巨慢,正常5秒慢的5分钟,谁也受不了。。。但是无论速度快慢,返回的结果都是正确无误的
3、DLL没有提供任何Closexxx,Freexxx之类的函数可用
4、GETMEM和FREEMEM是俺在尝试加上去是否可行,结果是GETMEM加上去没有效果,同时加上FREEMEM则发生异常
5、今天下午开始尝试动态加载DLL的方式,结果奇怪的事发生了,开始是一调用DLL直接抛出内存异常,后来我加上了GETMEM,居然就不报错了。。。汗,,速度问题还没来得及试,客户下班了,只好明天再说(DLL内含专网通讯,只有客户处能测试)
#30
给出函数的原型看看,要文档里面(应该是C/C++写的吧?)不是你在D调用的那个
#31
还有,你是用Delphi几?C里面的原型中的char *char,对应的是PAnsiChar,Delphi几开始默认的PChar是PWideChar了,你看看是不是这问题
#32
这个DLL也是DELPHI写的,版本不清楚。。。。俺用的是D6
#33
强烈要求给出文档说明,函数原型等。
#34
那就动态加载嘛,每次操作都是一次新的
#35
我觉得这个应该是dll的问题 想想看就算你在内存中创建3个pchan不释放 也不会造成你所说的那种卡的问题 我觉得应该是dll里面有其他的消耗内存的东西
#36
你作为一个星星还真牛X,什么叫没有ShareMem支撑就出错?我只看到PCHAR,没看到String;
另外,var P: Pchar,一看这样的参数,我就能猜到DLL的作者是什么样的想法.因为前不久我就遇到一个相同的做了N年DELPHI的人用相同的思路,让我纠结了很久,但到底是对方改正了,因为用了不久就出问题了
说正经的,楼主说用上GetMem和FreeMem,在FreeMem的时候会报错,那是因为DLL的作者在那个函数的内部改变了p1,p2的值,也就是说,你在FreeMem的时候已经不是你当初GetMem的值了,猜出这一点是根据你说在FreeMem的时候报错,你不信你就调试一下,看一下你调用前和调用后的时候P1,P2的值是不是一样.
如果是这样的话,有三种情况:
1: 即它也提供了一个释放的函数,调用完之后,用这个释放的函数去释放,否则就会有内存泄露.
2: P1,P2返回的是DLL中的全局变量,不需要额外释放.如果是这样话,你可以直接传进两个未初始化的指针进去,不也不去释放
2: P1,P2返回的是局部变量,即是堆栈中分配的内存,基本上,就只能自求多福了.这样的问题基本上是给你的DEMO表面没问题,但是你在用的时候随机性的出问题
说了一大堆,和你的程序运行快慢没多大关系,按道理来说,即使是内存有泄露,也不应该第三次就影响速度.毕竟还不知道代码,当前的问题,就是找出这个函数到底是怎么个意思