(高分求解)调用dll中返回的pchar类型值,释放出‘invalid pointer operation’错的问题(200)

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

zhhg975

Unregistered / Unconfirmed
GUEST, unregistred user!
调用的dll接口函数为‘function ReadData(pSN,pData :PChar;iNo,iPort:Integer):integer;stdcall;’调用此接口的函数定义如下:function GetBlockData(var BlockData : string;BlockNo :integer):string;var iPort, iRtn :integer; cSN, bData :Pchar;begin iPort := 1; GetMem(cSN,16); GetMem(bData,32); iRtn := ReadData(cSN,bData,BlockNo,iPort); if iRtn=99 then //表示返回成功 begin BlockData := bData; end else begin ShowMessage('读'+intTostr(BlockNo)+'出错!'); end; Finalize(bData); FreeMem(cSN); FreeMem(bData);end;第一次掉用上面的函数,一般没有问题,当多次调用上面的函数,在FreeMem(bData)时就会出现‘invalid pointer operation’的错误,请各位高手指教,如问题描述的不清楚请说明
 
Finalize(bData) 是什么
 
Finalize(bData)这句无所谓,加不加都一样出错的这个是看到一个网页上说释放前加这个的
 
在FreeMem(bData)前加一句判断语句试试。
 
function ReadData(pSN,pData :PChar;iNo,iPort:Integer):integer;stdcall;还是function ReadData(var pSN,pData :PChar;iNo,iPort:Integer):integer;stdcall;
 
to szhcracker:加什么判断语句?可否举个例子to dorry:就是我描述的那种声明,没有Var
 
GetMem(bData,32); // 分配了 32 个字节的内存if iRtn=99 then //表示返回成功 begin BlockData := bData; end else begin ShowMessage('读'+intTostr(BlockNo)+'出错!'); end;你注意一下:当出现‘invalid pointer operation’的错误时 bData 中的内容是什么?长度是多少?有可能你分配的大小不对,你可以把 FreeMem(cSN); FreeMem(bData);放到 try ... except ...end 中,出错的话就把 bData 中的内容Show出来。还可以试试去掉 GetMem(bData,32); 与 FreeMem(bData); 语句,有可能要改为 BlockData := StrPas(bData);让Delphi自己管理,看看能否正常运行。
 
把 FreeMem(bData); 改为 FreeMemory(bData); 试试。
 
to szhcracker:bData 里面的内容为16字节16进制数,分配的空间应该足够了吧,因为这两个Pchar类型参数是要从dll中取值回来的,不定义空间大小去掉GetMem(bData,32)直接用也是不行的to szhcracker:试过了你的方法,不起作用期盼高手不吝赐教啊!!
 
这样肯定是不行的了,bData在函数返回的时候已经释放了。有两种解决办法:一、用Windows的标准写法,GetBlockData调用时先GetMem,然后把传入过程,过程实现代码中不再需要对BlockData分配内存,直接赋值。二、把bData换成全局变量,GetBlockData调用后读完值后再用专门的函数去释放,如加一个FreeMyDataxxxx
 
1、是不是多进程产生数据冲突?看你的代码好像是从考勤机上读取数据吧?
 
to xianjun:现在的写法应该和你说的第一种办法相同的,就是在GetBlockData调用时先GetMem,然后把传入过程,过程实现的时候没有再对BlockData分配内存第二种方法不是很明白如何操作to zkktom:类似于读考勤设备,是单线程的,不存在多线程的问题
 
BlockData := strpas(bData);
 
cSN=GetMemory(16);ZeroMemory(cSN,16);bData=GetMemory(32);ZeroMemory(bData,32);tryiRtn := ReadData(cSN,bData,BlockNo,iPort);//注意看下函数要求的长度是不是16跟32//中间步骤能去掉的都先去掉finallyFreeMemory(bData);FreeMemory(cSN);end;//楼主改成这样看看呢
 
感觉ReadData函数调用后会改变传入参数的值,如果这样的话,是不是应该在申明时用var关键字?而且,一般传Pchar的话,应该是传入一个变量指针的吧.
 
感觉Pchar没必要var,因为传递的是指针,而函数里面最多只是改变这个指针的指向的值,指针应该不会变。要是integer,string等要用var,不过LZ可以加了看看,最好能把结果贴上来。
 
把DLL中对bData操作的相关代码发出来看看。
 
多人接受答案了。
 
后退
顶部