DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: jason_123_jason
今日帖子: 53
在线用户: 19
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 akai1203 (w-dins) ▲▲▲▲▲ -
普通会员
2018/12/3 16:15:12
标题:
TmemoryStream释放出错 浏览:386
加入我的收藏
楼主: Datasnap服务器上定义一个函数,返回类型是Tstream,如下

function TDSClient.GetDemo : TStream;
var
  stream: TMemoryStream;
  LQry: TFDQuery;
  Sa: TFDSchemaAdapter;
begin
  try
    Sa := TFDSchemaAdapter.Create(nil);
    LQry := TFDQuery.Create(nil);
    try
      with LQry do
      begin
        SchemaAdapter := Sa;
        Connection := dm.GetSYSConnection;
        SQL.Text := 'SELECT * FROM DEMO';
        Open;
      end;
      stream := TMemoryStream.Create;
      Sa.SaveToStream(stream, sfBinary);
      stream.Position := 0;
      Result := stream;
    except
      on e: Exception do
      begin
         raise ;
      end;
    end;
  finally
    FreeAndNil(LQry);
    FreeAndNil(Sa);
  end;

end;



在客户端这边 定义一个函数,调用服务器方法,如下

var
  DS: TDSClient;
  tbl: TFDMemTable;
  stream: TStream;
begin
    try
      tbl := TFDMemTable.Create(nil);
      stream := TMemoryStream.Create;
      DS := TDSClient.Create(con.DBXConnection);
      stream := DS.GetDemo //服务器上定义的函数
    finally
      FreeAndNil(tbl);
      FreeAndNil(DS);
      stream.free //这里出错,提示无效的指针操作
    end;
  end;

请教各位,这问题是什么原因
----------------------------------------------
-把学习当信仰
作者:
男 homejun (homejun) ★☆☆☆☆ -
盒子活跃会员
2018/12/3 16:49:35
1楼:  stream := DS.GetDemo
感觉这样不对吧?
----------------------------------------------
-delphi新资讯站 http://www.delphigear.cn
作者:
男 vga (vga) ★☆☆☆☆ -
盒子活跃会员
2018/12/3 17:22:16
2楼: stream := TMemoryStream.Create;          // 这里分配了一个

stream := DS.GetDemo //服务器上定义的函数       // 这里指向另外的地方
----------------------------------------------
-
作者:
男 looper (keyo) ★☆☆☆☆ -
盒子活跃会员
2018/12/3 17:48:23
3楼: 2楼已经指出了问题的关键,改成这样就可以了:

var
  DS: TDSClient;
  tbl: TFDMemTable;
  stream: TStream;
begin
    stream:= nil;
    try
      tbl := TFDMemTable.Create(nil);
      DS := TDSClient.Create(con.DBXConnection);
      stream := DS.GetDemo //服务器上定义的函数
    finally
      FreeAndNil(tbl);
      FreeAndNil(DS);
      if assigned(stream) then FreeAndNil(stream);
    end;
  end;
----------------------------------------------
虽千万人吾往矣!
作者:
男 akai1203 (w-dins) ▲▲▲▲▲ -
普通会员
2018/12/3 21:30:06
4楼: 还是一样的提示 无效指针操作
----------------------------------------------
-把学习当信仰
作者:
男 sxqwhxq (步惊云) ★☆☆☆☆ -
普通会员
2018/12/3 22:22:25
5楼: 用json,别用TStream
----------------------------------------------
-
作者:
男 akai1203 (w-dins) ▲▲▲▲▲ -
普通会员
2018/12/3 23:37:03
6楼: 暂时不考虑用json
----------------------------------------------
-把学习当信仰
作者:
男 iamdream (银河恒久远,梦想无止境!) ★☆☆☆☆ -
大贡献会员
2018/12/4 12:19:23
7楼: 估计是TDSClient自己释放了stream,你查看一下源代码。
----------------------------------------------
-广袤璀璨的银河,永无止境的梦想(梦无止境游银河) 偶的生活博客  偶的技术军事博客
作者:
男 jackalan (nVicen) ★☆☆☆☆ -
盒子活跃会员
2018/12/4 14:24:33
8楼: 这样返回TSTREAM问题多多吧吗?

建议你改下返回方式:

function TDSClient.GetDemo(var sResult: TStream):Boolean;
begin
   Result := False;
   if not Assigend(sResult) then Exit;
   ......
   ......
   Result := True;
end;

调用的时候,客户端:
stream := TMemoryStream.Create;
if DS.GetDemo(stream ) then 
begin
   .......
   .......
end
else MsgBox...or Reture Msg;
if Assigned(stream) then FreeAndNil(stream);
----------------------------------------------
简单做人,认真做事。
作者:
男 wang_80919 (Flying Wang) ▲▲▲▲△ -
普通会员
2018/12/4 14:33:14
9楼: 楼上正解。
不过我们一般用 ROSDK
就是这种类似的接口写法。
如果不是远程接口 var 都不用写。
但是 RO 的 var 流
输入的一个 a ,返回的肯定是 b
所以 a 和 b 都要销毁。

如果你不用 var 那么 a 的内容肯定不变。
也就没有返回内容。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 akai1203 (w-dins) ▲▲▲▲▲ -
普通会员
2018/12/4 17:36:11
10楼: 但是我这样写的时候,客户端提示我 [dcc32 Error] DSClient.pas(209): E2010 Incompatible types: 'TMemoryStream' and 'TStream'
----------------------------------------------
-把学习当信仰
作者:
男 akai1203 (w-dins) ▲▲▲▲▲ -
普通会员
2018/12/4 17:44:24
11楼: 我的环境是 delphi xe10.1 berlin  + win7
----------------------------------------------
-把学习当信仰
作者:
男 akai1203 (w-dins) ▲▲▲▲▲ -
普通会员
2018/12/4 17:47:06
12楼: to 8楼,是的,有内存泄漏
----------------------------------------------
-把学习当信仰
作者:
男 wang_80919 (Flying Wang) ▲▲▲▲△ -
普通会员
2018/12/4 17:48:13
13楼: 接 9 楼。
如果 流 不关心 输入。
那么 接口 应该用 out
RO SDK 调用的时候。
变量 不需要 初始化。
RO 接口会自动初始化。
只需要记得销毁就行。
----------------------------------------------
(C)(P)Flying Wang
作者:
男 akai1203 (w-dins) ▲▲▲▲▲ -
普通会员
2018/12/4 17:48:32
13楼: 大家可以试下,是不是datasnap不支持这个写法?
----------------------------------------------
-把学习当信仰
作者:
男 jjwwang (jjwwang) ▲▲▲▲▲ -
注册会员
2018/12/4 21:59:44
14楼:   DS := TDSClient.Create(con.DBXConnection);

TDSClient.Create应该还有一个重载的。后面带个boolean的参数。 

你改为
  DS := TDSClient.Create(con.DBXConnection, false); 试试
----------------------------------------------
学无止境
作者:
男 jjwwang (jjwwang) ▲▲▲▲▲ -
注册会员
2018/12/4 22:04:09
15楼: 另外也可以这样写
TXXX.GetPhoto(out Value: TStream): Boolean;
----------------------------------------------
学无止境
作者:
男 akai1203 (w-dins) ▲▲▲▲▲ -
普通会员
2018/12/4 22:48:19
16楼: 很奇怪的问题:

1,服务端的函数如果加 out 或 var ,客户端调用提示 VAR and OUT arguments must match parameter type exactly

2. 如果不加out 或var ,客户调用提示 invalid binary storage format 

3.TDSClient.Create应该还有一个重载的。后面带个boolean的参数。 
 --是的,如果不加false,则会有泄漏,必须加 False并手动在finlly 里释放
----------------------------------------------
-把学习当信仰
作者:
男 akai1203 (w-dins) ▲▲▲▲▲ -
普通会员
2018/12/4 23:15:38
17楼: 客户端获取到的流大小是0了
----------------------------------------------
-把学习当信仰
作者:
男 jjwwang (jjwwang) ▲▲▲▲▲ -
注册会员
2018/12/4 23:32:28
17楼: 1,服务端的函数如果加 out 或 var ,客户端调用提示 VAR and OUT arguments must match parameter type exactly
//----------
这个问题之前也遇到过,记不清是从XE的哪个版开如出这个错误的。之前是没有问题的,后来升级后就有问题了,代码没代,只是重新编译了一下。最早我好像是这样写的
TXXX.GetPhoto(out Value: TDBXStreamValue): boolean;

之所以会出现VAR and OUT arguments must match parameter type exactly这个问题,是TDBX内部有一些变化造成的。实际上也是有办法处理的,但由于担心后面会还会出其它的问题,最后来改成这样
TXXX.GetPhoto(out Value: TStream; DataSize: longword): boolean;

客户端大体上是copyfrom(v, DataSize)


关于第2个问题,后来一直没用过FD的数据集,都是转为JSON返回数据。
----------------------------------------------
学无止境
作者:
男 akai1203 (w-dins) ▲▲▲▲▲ -
普通会员
2018/12/5 10:09:53
18楼: 谢谢楼上及各位,最终还是改成了最初的形式,客户端用copystream,手动释放Dsclient和stream
----------------------------------------------
-把学习当信仰
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v2.1 版权所有 页面执行23.4375毫秒 RSS