delphi 7 string 的内存结构 (vc调用delphi dll) 别人提供的delphi动态库,我要用vc调用,但是库里的参数有 string 类型,不知道要怎么调用。问下delphi 7 string 的内存结构,看是否可以构造出 相同内存结构的 “string”传入。或者谁能告诉我 其他的调用办法? 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 从书上摘抄的字符串可以分为三大类:短字符串(ShortString)、长字符串(AnsiString /LongString)、宽字符串(WideString)。ShortString 在内存中占用0..255 字节,也就是说,它被固定分配256 字节。其中第0 字节存储字符串的实际长度,因此,一个ShortString 类型的变量实际最多存储255 个字符;但是,即使实际存储的字符不到255 个,它仍然在内存中霸道地占据256 字节。所以为了避免浪费,Object Pascal 又提供了另一种方法来声明更短的ShortString 变量:String[MaxLength]。一个String[MaxLength]类型的ShortString 占据0..MaxLength 共MaxLength+1 个字节。当然MaxLength 必须小于256。String 等同于AnsiString,否则等同于ShortStringDelphi中的String 一般等同于C/C++里的AnsiStringhttp://www.cnblogs.com/del/archive/2007/12/03/981563.html 这个可能真不行。能不能让那个人改一下,在dll中怎么能用string做参数,这本身就有问题,就如同在vc++中用CString做参数一样,为什么不用PChar?用string不知道会有什么隐式问题,到时候调试都困难。 没什么问题delphi7的string类型,就是一块连续的内存,其中前四个字节是引用计数4字节 再后面是长度4字节, 后面就是内容ansistring,一个字符占一个字节。传递时把地址传入即可 一般做成dll的输出函数了,参数不会使用string而是pchar了的吧? 用PAnsiChar吧用string不行的 理论上应该可以。我手头没有c++,所以没法测试。先从delphi中说起。delphi7的String结构如下 PStrRec = ^StrRec; StrRec = packed record refCnt: Longint; //引用计数 length: Longint; //字符串长度 PStr: Pointer; //指向实际字符串的指针。 end;首先你先在c中声明一个类似的结构体,然后,你动态开辟一个这个结构体的内存,假设是PS设置其中的 refCnt 至少要大于2,但是别设置成$FFFFFFFF(常量字符串被设置成这个),填写length域为字符串长度,填写PStr域指向实际字符串的首地址。然后,将这个结构中的 PStr 作为参数传递给dll的String参数(注意,是PStr 域 ,不是这个结构体的首地址 PS)。估计这样能行。用完了,记得在c中释放相关内存,呵呵 哦,上面给的结构有错误,抱歉啊,重来。应该是这样: StrRec = packed record refCnt: Longint; //引用计数,4个字节 length: Longint; //字符串长度,4个字节 Str:array[0..length-1] of Char; //实际字符串,实际长度是length中的长度 end;大概就是这样一个结构。你在c首先开辟一块内存,其长度是你原始字符串的长度+4+4以上面的格式将字符串放在Str中,并将refCnt结构填写大于2的数,将length填写为实际字符串长度。然后,将Str的地址作为参数传递。其实,也就是开辟一个字符串长度+8的内存,然后将前4个字节填入数字2,将紧接着的4个字节添如字符串长度,再在随后的地方,把字符串的内容复制过去,最后,跳过前面8个字节,把这个内存中的实际字符串的地址传给dll,呵呵 c/c++可以写成:typedef struct{ int refCount; int lenght; TCHAR data[1];}dString, *LPDString; 在Delphi7中调试,感觉应该传送自内容开始的地址而不是从引用计数开始的地址 结构体是正确的.但Delphi真正用的string其实是个指针.而且是指向data部分的指针,也就是refCount,lenght都是在负偏移的位置.另外Delphi2009,2010,XE及其以后版本增加了一个CodePage的成员.表示字符串语言的编码. 我用的是Delphi2010.Delphi2009之前只要去掉CodePage和elemSize是一样的.procedure TForm1.Button1Click(Sender: TObject);type PStrRec = ^StrRec; StrRec = packed record codePage: Word; //语言,Delphi2009之前没有这个域 elemSize: Word; //语言,每个元素(可以理解成字符)大小,Delphi2009之前没有这个域 refCnt: Longint; //引用计数 length: Longint; //长度 data : array[0..0] of Char; //数据,实际长度以length+1为准,最后有一个#0 end;var s : string; p : Integer; pstr : PStrRec;begin s := '1000'; //如果是字符串常量的话引用计数为-1. s := s + 'a';//这次引用计数应该是1 p := Integer(s);//string本身是个指针,指向StrRec.data pstr := PStrRec(p - 12); //取到 StrRec 的地址 ShowMessage(Format('语言:%d;元素大小:%d;引用计数:%d;字符串长度%d;字符串内容:"%s"',[pstr.codePage, pstr.elemSize, pstr.refCnt, pstr.length, PChar(@pstr.data)]));end; 关于Reset(lc_file)运行错误问题 公司要做这样一个程序---把MEMO中的数据以一行为单位,上传到网上的数据库(为一个字段) 用UDP或TCP 求助:Tmainmenu控件的字体如何修改,谢谢 delphi访问access数据库 高手快来!这个问题很有难度的哦!! 遠程圖像的顯示???? 如何从记录集中取数据!! 一个关于反复调用窗体的问题 我准备把7月份的贴子全部结了大家认为如何? Delphi 7中 TIdUDPServer 的接收端怎么写代码? 关于Opengl3.1的疑惑 sql server 2000 表中Numeric类型字段只能输入精度4位的数?
(WideString)。
ShortString 在内存中占用0..255 字节,也就是说,它被固定分配256 字节。其中第0 字节存储字符
串的实际长度,因此,一个ShortString 类型的变量实际最多存储255 个字符;但是,即使实际存储的字
符不到255 个,它仍然在内存中霸道地占据256 字节。所以为了避免浪费,Object Pascal 又提供了另一
种方法来声明更短的ShortString 变量:String[MaxLength]。一个String[MaxLength]类型的ShortString 占
据0..MaxLength 共MaxLength+1 个字节。当然MaxLength 必须小于256。
String 等同于AnsiString,否则等同于ShortStringDelphi中的String 一般等同于C/C++里的AnsiString
http://www.cnblogs.com/del/archive/2007/12/03/981563.html
delphi7的string类型,就是一块连续的内存,其中前四个字节是引用计数4字节 再后面是长度4字节, 后面就是内容ansistring,一个字符占一个字节。
传递时把地址传入即可
用string不行的
delphi7的String结构如下 PStrRec = ^StrRec;
StrRec = packed record
refCnt: Longint; //引用计数
length: Longint; //字符串长度
PStr: Pointer; //指向实际字符串的指针。
end;首先你先在c中声明一个类似的结构体,然后,你动态开辟一个这个结构体的内存,假设是PS
设置其中的 refCnt 至少要大于2,但是别设置成$FFFFFFFF(常量字符串被设置成这个),
填写length域为字符串长度,填写PStr域指向实际字符串的首地址。
然后,将这个结构中的 PStr 作为参数传递给dll的String参数(注意,是PStr 域 ,不是这个结构体的首地址 PS)。
估计这样能行。
用完了,记得在c中释放相关内存,呵呵
应该是这样:
StrRec = packed record
refCnt: Longint; //引用计数,4个字节
length: Longint; //字符串长度,4个字节
Str:array[0..length-1] of Char; //实际字符串,实际长度是length中的长度
end;
大概就是这样一个结构。你在c首先开辟一块内存,其长度是你原始字符串的长度+4+4
以上面的格式将字符串放在Str中,并将refCnt结构填写大于2的数,将length填写为实际字符串长度。
然后,将Str的地址作为参数传递。
其实,也就是开辟一个字符串长度+8的内存,然后将前4个字节填入数字2,将紧接着的4个字节添如字符串长度,再在随后的地方,把字符串的内容复制过去,最后,跳过前面8个字节,把这个内存中的实际字符串的地址传给dll,呵呵
{
int refCount;
int lenght;
TCHAR data[1];
}dString, *LPDString;
结构体是正确的.但Delphi真正用的string其实是个指针.而且是指向data部分的指针,也就是refCount,lenght都是在负偏移的位置.
另外Delphi2009,2010,XE及其以后版本增加了一个CodePage的成员.表示字符串语言的编码.
procedure TForm1.Button1Click(Sender: TObject);
type
PStrRec = ^StrRec;
StrRec = packed record
codePage: Word; //语言,Delphi2009之前没有这个域
elemSize: Word; //语言,每个元素(可以理解成字符)大小,Delphi2009之前没有这个域
refCnt: Longint; //引用计数
length: Longint; //长度
data : array[0..0] of Char; //数据,实际长度以length+1为准,最后有一个#0
end;
var
s : string;
p : Integer;
pstr : PStrRec;
begin
s := '1000'; //如果是字符串常量的话引用计数为-1.
s := s + 'a';//这次引用计数应该是1 p := Integer(s);//string本身是个指针,指向StrRec.data
pstr := PStrRec(p - 12); //取到 StrRec 的地址
ShowMessage(Format('语言:%d;元素大小:%d;引用计数:%d;字符串长度%d;字符串内容:"%s"',[pstr.codePage, pstr.elemSize, pstr.refCnt, pstr.length, PChar(@pstr.data)]));
end;