特急——寻找string变widestring的解决方案——100大洋(100分)

  • 主题发起人 主题发起人 dreamer
  • 开始时间 开始时间
D

dreamer

Unregistered / Unconfirmed
GUEST, unregistred user!
我在开发三层时,为了简化数据传递,将参数及返回值都有一个ThttpMess封装起来。
我的做法是将ThttpMess先转化成String,但由于COM只支持WideString,而Delphi在从
String向WideString转化的过程中,竟改变了信息。
有没有方案绝对保证string变widestring后,还能保持真我?
 
本来就是真的
没有改变
 
你的变成什么样了?怎么会变呢?
 
变就变了,凡正不保险。我逐个字符地比较过。
不过我用其它方案解决了。
先将String变成Variant字节流,
这样就万无一失了。
 
看看这个吧:改变了什么?自己看:
procedure TForm1.Button1Click(Sender: TObject);
var
aa:widestring;
bb,cc:string;
begin
bb:='大富翁abc';
aa:=bb;
Label1.Caption:=IntToStr(length(aa));
Label2.Caption:=aa;
cc:=aa;
Label3.Caption:=IntToStr(length(cc));
Label4.Caption:=cc;
end;
 
决不可能,打死我也不相信会变
 
string 与 widestring 的相互转换本来是系统自动做, 你何乐不为呢, 以怎么会出错
 
你可以把D5的那个.pas文件中的String改成WideString后再重新编译~!
 
大家有没有看,注意Label1,Label3两个值不同了。
但不管如何变,都可以把WideString转换为String
 
系统自动转换的。
 
string做参数的时候肯定会变:
typedef struct _PSHEDULERHEADER
{
int MediaType;

int FrameType;
int FrameSequence;
int FrameSize;

}PSHEDULERHEADER;
小弟我用VC写的activex,输出参数为上面这个结构,具体为LPCTSTR即BSTR,和Delphi对应的是
widestring,结果我使用类型强制转化后,前面两个只是正确的,后面两个无法转换.但是如果
四个参数都小于896的时候不会出错,总之碰到了很多问题.
delphi中我如下使用:
type TPSHEDULERHEADER= packed RECORD
MediaType: integer;

FrameType: integer;

FrameSequence: integer;

FrameSize: integer;

end;

type PPSHEDULERHEADER = ^TPSHEDULERHEADER;
procedure TForm1.BitBtn5Click(Sender: TObject);
var
senddata: array[1..50000] of char;
timestamp:integer;
begin
fillchar(senddata,sizeof(senddata),'a');
PPSHEDULERHEADER(@senddata)^.MediaType := 11111;
PPSHEDULERHEADER(@senddata)^.FrameType := 22222;
PPSHEDULERHEADER(@senddata)^.FrameSequence := 33333;
PPSHEDULERHEADER(@senddata)^.FrameSize := 44444;

DemoActivex.SendData(senddata);
end;

各位可以试试!
 
这种转换后,长度的变化是必然的,因为字符集的标准都不同,但内容是正常的,而且转换的
过程是系统自动完成的
 
>>看看这个吧:改变了什么?自己看:
procedure TForm1.Button1Click(Sender: TObject);
var
aa:widestring;
bb,cc:string;
begin
bb:='大富翁abc';
aa:=bb;
Label1.Caption:=IntToStr(length(aa));
Label2.Caption:=aa;
cc:=aa;
Label3.Caption:=IntToStr(length(cc));
Label4.Caption:=cc;
end;
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
你到底看了帮助文件没有?
label1 = 6 是因为这个字符串有六个 Unicode 字符。
label3 = 9 因为每个汉字是两个字符。
哪儿错了?
 
有没有搞错?
只比较长度的话只要有中文字符在里面当然不一样了,
你把WideString再强制转换成String不就行了,
照mikedeakins说的做个试验就知道了。
 
mikedeakins:
我没有说有错,这段程序只想告诉 dreamer
WideString和String有什么不同,它们可以转换
string变widestring后再变回string还是原来的string;
 
了解,我没有正确领会精神:-)
 
其实呢,我用的是最简单的代码
S,S1:String;
WS:WideString;
begin
……
WS:=S;//这个出错。
S1:=WS;//这个没问题。
我比较的是S和S1,而且是逐个字符地比较,结果在某个位置开始变异了。

一般说简单的字串转换是不会错的,但是因为我赋予的字串实际上是个二进制流,
所以会有莫名的错误。
凡正问题已经解决了,我将字串转换成Variant字节流,这样就万无一失了。
也警介在家,在编程中,String和WideString不是绝对可以互换的,
复杂的数据流传输还是创建一个varbyte的Variant数组。
 
请问 Dreamer :
*你们是以 Thttpmess 类型作为函数的回传参数类型吗?还是用OleVariant作为函数的
回传参数,如果是前者的话,能否将Thttpmess的类型告知小弟?
*我们也正在做MTS/COM+的一个系统,但有一个概念性的东西还是不太明白,我是按照李
维书上的方法做一个例子: 由MTSDataMoudle,MTSObject,PJClient三部分组成,在MTSDataMoudel
加入ADOQuery1,DataProvider1,设置好相关属性,在MTSObject中加入DCOMConnection1,Client-
DataSet1,设置好相关属性。此时客户端想添加一条记录,如通过SQL语句来添加,相应的 SQL 语句
是在哪一个模块中哪一个控件中执行呢? 真的很困惑……
肯请回答@_@ 我的 E-Mail:wuze@elong.com 能交流吗?
 
S,S1:String;
WS:WideString;
begin
……
WS:=S;//这个出错。
//你改为:ws:=widestring(s);就ok了
S1:=WS;//这个没问题。
 
to zgdtxf:你的方法我试过了,没用。
to woo:关于MTS我还没用,没法回答你。关于第一个问题,COM支持的类型并不多,你可以查看
一下帮助,所以不可能用自定义的类型做参数。复杂的数据流转输都建筑在Variant数组之上,
可以说,整个MIDAS体系也就建筑在Variant数组之上。但是用Variant数组做传输,对于大量复杂的参数和结果
不容易维护。所以我一般是先将参数封闭在一个THttpMess结构里,再将这个结构转化成Variant字节流(
最先是转化成WideString,发现出了问题),然后在另一端再重新生成THttpMess.
Varinat字节流真是太伟大了,我准备写两个Stream流和Variant字节流互换的函数,以后
从数据从VCL体系向COM体系转换就容易了。
可以说,Stream流是VCL的基石,Variant字节流是COM的根基。
 
后退
顶部