2597 lines
70 KiB
Plaintext
2597 lines
70 KiB
Plaintext
Unit cstructurelib;
|
|
{**
|
|
@explan(说明)内存对象工具 %%
|
|
@example(范例1)
|
|
|
|
|
|
**}
|
|
|
|
(*
|
|
概览:
|
|
天软科技
|
|
20171215 添加注释
|
|
20170904 修改,提供
|
|
ctypedefine 函数(定义结构体)
|
|
tcstruct 类(定义结构体)
|
|
tcpointer 类(结构体内存管理)
|
|
|
|
c语言内存结构相关功能库
|
|
1.实现c结构体和tsl的交互
|
|
|
|
提供方法
|
|
csstotslarray2(data) 将c的结构体字符串形式 转换为tsl array 结构;由于宏定义的原因需要手工修改一下,但是也提高了转换效率
|
|
例1:
|
|
data := "
|
|
typedef struct tagNMTBHOTITEM {
|
|
NMHDR hdr;
|
|
int idOld;
|
|
int idNew;
|
|
DWORD dwFlags;
|
|
} NMTBHOTITEM, *LPNMTBHOTITEM;
|
|
";
|
|
r := csstotslarray2(data);
|
|
typ1 := ctypedefine("tagNMTBHOTITEM",r);
|
|
return typ1.show;//打印结构体排布情况
|
|
|
|
使用范例:
|
|
c中定义:
|
|
struct ts3 {
|
|
char a[3];
|
|
double b;
|
|
};
|
|
struct ts2 {
|
|
char a[5];
|
|
int b[3];
|
|
ts3 e;
|
|
ts3* c;
|
|
};
|
|
struct ts1 {
|
|
char a[3];
|
|
ts2 m1;
|
|
|
|
|
|
};
|
|
|
|
|
|
*)
|
|
|
|
Interface
|
|
uses parserch;
|
|
//c结构体转换为tsl对象结构由于识别有限结果需要手工修改**************************
|
|
//function writeloglen(len);
|
|
function MemoryAlignmentCalculate(data,baselen,ssize,pack);
|
|
function ReadStringFromPtr(ptr);
|
|
function WriteStringToPtr(ptr,str);
|
|
function ReadBytesFromPtr(ptr,L);
|
|
function WriteBytesToPtr(ptr,bytes);
|
|
function parserctypestr(ts,t,s,n);
|
|
function dealcppcomment(strs);
|
|
function csstotslarray(csstr,tname);
|
|
function csstotslarray2(csstr,iv);
|
|
function csstotslarray3(ret,iv);
|
|
function cstructtotslclass(data,name,fs);
|
|
function tslarraytocstructcalc(data,alim,bsi,ssize);//计算对其长度 参数 data 结构体,alim 对其 默认为8;bsi 基础地址默认为0,ssize 结构体大小 返回值
|
|
function ctypedefine(name,stc,alim,f);//结构体定义
|
|
//内存对象分配,释放类;
|
|
type tmemoryclass=class
|
|
{**
|
|
@explan(说明)存对象分配,释放类 %%
|
|
@param(_blocks)(array) 分配的内存块;以地址为索引的数组,值为分配的大小 %%
|
|
@param(_tool)(aefclassobj_) 内存管理底层工具 %%
|
|
**}
|
|
protected
|
|
_blocks; //分配的内存块;以地址为索引的数组,值为分配的大小;
|
|
static _tool;
|
|
public
|
|
class function GetPointerSize();
|
|
begin
|
|
{**
|
|
@explan(说明) 获得指针字节数 %%
|
|
**}
|
|
{$IFDEF win64}
|
|
return 8;
|
|
{$ELSE}
|
|
return 4;
|
|
{$ENDIF}
|
|
end
|
|
function opblocks(p,f,v); //内存存储操作
|
|
begin
|
|
{**
|
|
@explan(说明)内存存储操作 %%
|
|
@param(p)(integer) 内存指针 %%
|
|
@param(f)(integer) 操作码 0 获取 1 设置 2 删除 %%
|
|
**}
|
|
ps := inttostr(p);
|
|
if f=0 then //获取
|
|
begin
|
|
return _blocks[ps];
|
|
end else
|
|
if f=1 then //设置
|
|
begin
|
|
r := _blocks[ps];
|
|
_blocks[ps]:= v;
|
|
return r;
|
|
end else
|
|
if f=2 then //删除
|
|
begin
|
|
return reindex(_blocks,array(ps:nil));
|
|
end
|
|
end
|
|
function tmalloc(n,f); //分配
|
|
begin
|
|
{**
|
|
@explan(说明)内存分配 %%
|
|
@param(n4)(integer) 长度 %%
|
|
@param(f)(integer) 操作码 0 获取 1 设置 2 删除 %%
|
|
**}
|
|
if n>0 then
|
|
begin
|
|
p := _tool.tmalloc(n);
|
|
if p <> 0 then
|
|
begin
|
|
if f=1 then _tool.tmset(p,n);
|
|
opblocks(p,1,n);
|
|
end
|
|
end
|
|
return p;
|
|
end
|
|
function tfree(p); //析构
|
|
begin
|
|
{**
|
|
@explan(说明)释放内存 %%
|
|
@param(p)(integer) 指针 %%
|
|
**}
|
|
pt := opblocks(p,0);
|
|
if pt then
|
|
begin
|
|
_tool.tfree(p);
|
|
opblocks(p,2);
|
|
end
|
|
return pt;
|
|
end
|
|
function trealloc(p,n,f); //重分配
|
|
begin
|
|
{**
|
|
@explan(说明)重分配 %%
|
|
@param(p)(integer) 指针 %%
|
|
@param(n)(integer) 大小 %%
|
|
@param(f)(integer) 操作码 0 获取 1 设置 2 删除 %%
|
|
**}
|
|
pt := opblocks(p,0);
|
|
if pt and n>0 then
|
|
begin
|
|
//writeloglen(n);
|
|
ptt := _tool.trealloc(p,n);
|
|
if ppt <> pt then
|
|
begin
|
|
opblocks(p,2);
|
|
if ptt <> 0 then
|
|
begin
|
|
if f=1 then _tool.tmset(ptt,n);
|
|
opblocks(ptt,1,n);
|
|
end
|
|
end
|
|
end
|
|
return ptt;
|
|
end
|
|
class function mtool(); //获得内存管理工具
|
|
begin
|
|
{**
|
|
@explan(说明)获取底层操作工具 %%
|
|
@return (aefclassobj_)内存底层管理工具
|
|
**}
|
|
if not ifobj(_tool)then _tool := new aefclassobj_();
|
|
return _tool;
|
|
end
|
|
function create();
|
|
begin
|
|
_blocks := array();
|
|
mtool();
|
|
end
|
|
function destroy();virtual;
|
|
begin
|
|
for i,v in _blocks do //析构分配的字符串空间
|
|
begin
|
|
if ifstring(i)and ifnumber(v)then
|
|
begin
|
|
_tool.tfree(strtoint(i));
|
|
//echo "\r\n析构:",i;
|
|
end
|
|
end
|
|
_blocks := array();
|
|
end
|
|
end
|
|
|
|
//旧的内存管理类,不支持**类型
|
|
type ctslctrans = class(tmemoryclass)
|
|
(**
|
|
@example(范例--内存管理--1)
|
|
sa := array(("f","int",2),
|
|
("a","char[3]","cd"),
|
|
("b","user",(("c","char[5]","ab"),
|
|
("d","int",5))),
|
|
("c","user*",(("c","char[5]","ab"),
|
|
("d","int",5),
|
|
("e","char*","abcd")))
|
|
|
|
);
|
|
data := tslarraytocstructcalc(sa);
|
|
o := new ctslctrans(data);
|
|
return echo o._size_(),"****",
|
|
o._getvalue_("c")._size_(),"***",
|
|
o._getvalue_("b")._size_,"***",o._getvalue_("c")._getvalue_("e");
|
|
**)
|
|
private
|
|
_nomalloc;
|
|
//protected
|
|
//_blocks ;//分配的内存块;以地址为索引的数组,值为分配的大小;
|
|
_ptr;//对象地址
|
|
_objs;//子对象
|
|
_objstart;//起始位置
|
|
_objsize;//字节长度
|
|
_objst;//类型
|
|
_objss;//长度
|
|
_charexten;//字符串扩展
|
|
_size;//大小
|
|
function setcharext(v); //设置字符串*是否可以扩展
|
|
begin
|
|
_charexten := v;
|
|
end
|
|
function _setvalue_base(i,v); //根据索引 设置值,目前值不能设置基础值
|
|
begin
|
|
{**
|
|
@explan(说明)根据索引 设置值,目前只能设置基础值 %%
|
|
@param(i)()索引 %%
|
|
@param(v)()值 %%
|
|
**}
|
|
p := _objs[i];
|
|
l := _objss[i];
|
|
ret :=-1;
|
|
//echo tostn(array(_objst[i],i,v)),",";
|
|
case _objst[i]of
|
|
"char":
|
|
begin
|
|
if ifstring(v)and length(v)<= l then
|
|
begin
|
|
_tool.writestr(p,v);
|
|
ret := 1;
|
|
end
|
|
end
|
|
"uint":
|
|
begin
|
|
if ifnumber(v)then
|
|
begin
|
|
_tool.writeuint(p,v);
|
|
ret := 1;
|
|
end
|
|
end
|
|
"int":
|
|
begin
|
|
if ifnumber(v)then
|
|
begin
|
|
_tool.writeint(p,v);
|
|
ret := 1;
|
|
end
|
|
end
|
|
"intptr":
|
|
begin
|
|
if ifnumber(v)then
|
|
begin
|
|
//echo "wirtptr\r\n";
|
|
_tool.writeptr(p,v);
|
|
ret := 1;
|
|
end
|
|
ret := 1;
|
|
end
|
|
"double":
|
|
begin
|
|
if ifnumber(v)then
|
|
begin
|
|
_tool.writedouble(p,v);
|
|
ret := 1;
|
|
end
|
|
end
|
|
"float":
|
|
begin
|
|
if ifnumber(v)then
|
|
begin
|
|
_tool.writefloat(p,v);
|
|
ret := 1;
|
|
end
|
|
end
|
|
"char*":
|
|
begin
|
|
if ifstring(v)and length(v)<= l then
|
|
begin
|
|
//echo tostn(array("char*",i,l,v)),",";
|
|
p1 := _tool.readptr(p);
|
|
_tool.writestr(p1,v);
|
|
//echo tostn(array(p,p1, _tool.readstr(p1)));
|
|
ret := 1;
|
|
end else
|
|
if ifstring(v)and _charexten then
|
|
begin
|
|
p1 := pointmalloc(i,v);
|
|
_tool.writestr(p1,v);
|
|
ret := 1;
|
|
end
|
|
end
|
|
"byte":
|
|
begin
|
|
if ifnumber(v)then
|
|
begin
|
|
_tool.writebyte(p,v);
|
|
ret := 1;
|
|
end
|
|
end
|
|
"short":
|
|
begin
|
|
if ifnumber(v)then
|
|
begin
|
|
_tool.writeshort(p,v);
|
|
ret := 1;
|
|
end
|
|
end
|
|
"shortarray":
|
|
begin
|
|
if arraynumberchek(v)and length(v)<= l then
|
|
begin
|
|
_tool.writeshorts(p,length(v),v);
|
|
ret := true;
|
|
end
|
|
end
|
|
"bytearray":
|
|
begin
|
|
if arraynumberchek(v)and length(v)<= l then
|
|
begin
|
|
//echo tostn(array("bytearray",i,l,v)),",";
|
|
_tool.writebytes(p,length(v),v);
|
|
ret := true;
|
|
end
|
|
end
|
|
"intarray":
|
|
begin
|
|
if arraynumberchek(v)and length(v)<= l then
|
|
begin
|
|
_tool.writeints(p,length(v),v);
|
|
ret := true;
|
|
end
|
|
end
|
|
"uintarray":
|
|
begin
|
|
if arraynumberchek(v)and length(v)<= l then
|
|
begin
|
|
_tool.writeuints(p,length(v),v);
|
|
ret := true;
|
|
end
|
|
end
|
|
"doublearray":
|
|
begin
|
|
if arraynumberchek(v)and length(v)<= l then
|
|
begin
|
|
_tool.writedoubles(p,length(v),v);
|
|
ret := true;
|
|
end
|
|
end
|
|
//else echo "\r\n error: type:",_objst[i];
|
|
end;
|
|
return ret;
|
|
end
|
|
function pointmalloc(v0,v2); //指针内存处理
|
|
begin
|
|
{**
|
|
@explan(说明)指针内存处理 %%
|
|
@param(v0)() 索引%%
|
|
@param(v2)() 数据%%
|
|
**}
|
|
ps := _objs[v0];
|
|
op := _tool.readptr(ps);
|
|
if ifstring(v2)then
|
|
begin
|
|
len := length(v2)+1;
|
|
end else
|
|
if ifnumber(v2)then
|
|
begin
|
|
len := v2;
|
|
end else
|
|
if ifarray(v2)then
|
|
begin
|
|
len := length(v2);
|
|
end
|
|
if opblocks(op,0)then
|
|
begin
|
|
//writeloglen(len);
|
|
p := trealloc(op,len); //重分配
|
|
end else
|
|
begin
|
|
p := tmalloc(len); //分配
|
|
end
|
|
if p=0 then raise "内存分配失败";
|
|
if ifstring(v)then _objss[v0]:= len-1; //长度
|
|
else _objss[v0]:= len;
|
|
_objsize[v0]:= len;
|
|
_tool.tmset(p,len); //初始化
|
|
_tool.writeptr(ps,p);
|
|
return p;
|
|
end
|
|
{**
|
|
@explan(说明)旧的内存管理类,不支持**类型 %%
|
|
@param(_ptr)(integer) 对象地址 %%
|
|
@param(_objs)(array) 子对象 %%
|
|
@param(_objstart)(integer) 开始位置 %%
|
|
@param(_objsize)(integer) 字节长度 %%
|
|
@param(_objst)(string) 类型 %%
|
|
@param(_objss)(integer) 类型长度%%
|
|
@param(_charexten)(bool) 字符串扩展 %%
|
|
@param(_size)(integer) 大小 %%
|
|
**}
|
|
public
|
|
function operator[1](index,v);
|
|
begin
|
|
{**
|
|
@explan(说明) 设置成员 %%
|
|
@param(index)(tslobj) 下标 %%
|
|
@param(v)(tslobj) 值
|
|
**}
|
|
return _setvalue_(index,v);
|
|
end
|
|
function operator[](index);
|
|
begin
|
|
{**
|
|
@explan(说明) 获取成员 %%
|
|
@param(index)(tslobj) 下标 %%
|
|
@return(tslobj) 返回值 %%
|
|
**}
|
|
return _getvalue_(index);
|
|
end
|
|
function create(data,ptr,ifset); //构造
|
|
begin
|
|
{**
|
|
@explan(说明)构造 %%
|
|
@param(data)(array) 计算好的内存分布%%
|
|
@param(ptr)(integer) 内存指针%%
|
|
@param(ifset)(integer) 递归构造时使用%%
|
|
**}
|
|
class(tmemoryclass).create();
|
|
_ptr := 0;
|
|
if not(ifarray(data)and mcols(data)>3)then
|
|
begin
|
|
raise "内存管理对象构造错误!";
|
|
return;
|
|
end
|
|
_objsize := _objstart := _blocks := _objss := _objst := _objs := array();
|
|
ldata := length(data)-1;
|
|
_size := data[ldata,3]+data[ldata,4]-data[0,3];
|
|
if ifnumber(ptr)and ptr then
|
|
begin
|
|
_ptr := ptr;
|
|
_nomalloc := true;
|
|
for i,v in data do
|
|
begin
|
|
v0 := v[0]; //id
|
|
v1 := v[5]; //type
|
|
_objst[v0]:= v1;
|
|
_objss[v0]:= v[6];
|
|
_objstart[v0]:= v[3]; //开始位置
|
|
_objsize[v0]:= v[4]; //字节长度
|
|
v3 := v[3];
|
|
v2 := v[2];
|
|
//_iindex[i] := v0;
|
|
if v1="user*" then
|
|
begin
|
|
if ifset then
|
|
begin
|
|
no := new ctslctrans(v2,nil,nil);
|
|
_objs[v0]:= no;
|
|
_tool.writeptr(ptr+v3,no._getptr_); //修改原有的值
|
|
end else
|
|
begin
|
|
tptr := _tool.readptr(ptr+v3); //提取原有的值
|
|
_objs[v0]:= new ctslctrans(v2,tptr,nil);
|
|
end
|
|
end else
|
|
if v1="userarray" then
|
|
begin
|
|
_objs[v0]:= new ctslctrans(v2,ptr,ifset);
|
|
end else
|
|
_objs[v0]:= ptr+v3;
|
|
if ifset then
|
|
begin
|
|
if v1="char*" then
|
|
begin
|
|
pointmalloc(v0,v2);
|
|
end
|
|
_setvalue_base(v0,v2);
|
|
end
|
|
end
|
|
end else
|
|
begin
|
|
_ptr := tmalloc(_size,1);
|
|
//_tool.tmset(_ptr,size);
|
|
for i,v in data do
|
|
begin
|
|
v0 := v[0];
|
|
v1 := v[5];
|
|
_objst[v0]:= v1;
|
|
_objss[v0]:= v[6];
|
|
_objstart[v0]:= v[3]; //开始位置
|
|
_objsize[v0]:= v[4]; //字节长度
|
|
v2 := v[2];
|
|
v3 := v[3];
|
|
_objs[v0]:= _ptr+v3;
|
|
if v1="user*" then
|
|
begin
|
|
no := new ctslctrans(v2,nil,nil);
|
|
_objs[v0]:= no;
|
|
_tool.writeptr(_ptr+v3,no._ptr);
|
|
end else
|
|
if v1="userarray" then
|
|
begin
|
|
no := new ctslctrans(v2,_ptr,true);
|
|
_objs[v0]:= no;
|
|
end else
|
|
if v1="char*" then
|
|
begin
|
|
pointmalloc(v0,v2); //内存分配
|
|
end
|
|
_setvalue_base(v0,v2);
|
|
end
|
|
end
|
|
//echo "\r\n内存管理:" ,_ptr,tostn(data);
|
|
end
|
|
function _getptr2_();
|
|
begin
|
|
{**
|
|
@explan(说明)获得内存指针 %%
|
|
|
|
**}
|
|
x := 0;
|
|
for i,v in _objstart do
|
|
begin
|
|
x := v;
|
|
break;
|
|
end
|
|
return _getptr_()+x;
|
|
end
|
|
function _getptr_(); //获得地址
|
|
begin
|
|
{**
|
|
@explan(说明)获得内存指针 %%
|
|
|
|
**}
|
|
return _ptr;
|
|
end
|
|
function _setcptr_(ptr); //设置对象地址
|
|
begin
|
|
{**
|
|
@explan(说明)设置对象地址 %%
|
|
**}
|
|
if ifnumber(ptr)and ptr and _nomalloc then _ptr := ptr;
|
|
end
|
|
function _size_(); //获得对象占用空间大小
|
|
begin
|
|
{**
|
|
@explan(说明)获得内存大小 %%
|
|
**}
|
|
return _size;
|
|
end
|
|
function _setvalue_(i,v);virtual;
|
|
begin
|
|
_setvalue_base(i,v);
|
|
end
|
|
function arraynumberchek(v); //数字数组检查
|
|
begin
|
|
{**
|
|
@explan(说明)数字数组检查 %%
|
|
@param(v)(array) %%
|
|
**}
|
|
ok := 0;
|
|
if ifarray(v)and length(v)>0 then
|
|
begin
|
|
ok := true;
|
|
for i,vi in v do if not ifnumber(vi)then
|
|
begin
|
|
ok := false;
|
|
break;
|
|
end
|
|
end
|
|
return ok;
|
|
end
|
|
function _getvalue_(v);virtual; //根据索引v获得对应值
|
|
begin
|
|
{**
|
|
@explan(说明)根据索引v获得对应值 %%
|
|
@param(v)() 索引%%
|
|
**}
|
|
p := _objs[v];
|
|
//echo tostn(_objs);
|
|
l := _objss[v];
|
|
case _objst[v]of
|
|
"char":
|
|
begin
|
|
ret := _tool.readstr(p);
|
|
end
|
|
"int":
|
|
begin
|
|
ret := _tool.readint(p);
|
|
end
|
|
"intptr":
|
|
begin
|
|
ret := _tool.readptr(p);
|
|
end
|
|
"double":
|
|
begin
|
|
ret := _tool.readdouble(p);
|
|
end
|
|
"float":
|
|
begin
|
|
//echo "get:",p,"\r\n";
|
|
ret := _tool.readfloat(p);
|
|
end
|
|
"char*":
|
|
begin
|
|
p1 := _tool.readptr(p);
|
|
//echo "\r\nstr:",p,"***",p1;
|
|
ret := _tool.readstr(p1);
|
|
//echo "\r\n",(ret);
|
|
end
|
|
"byte":
|
|
begin
|
|
ret := _tool.readbyte(p);
|
|
end
|
|
"short":
|
|
begin
|
|
ret := _tool.readshort(p);
|
|
end
|
|
"shortarray":
|
|
begin
|
|
ret := _tool.readshorts(p,l);
|
|
end
|
|
"bytearray":
|
|
begin
|
|
ret := _tool.readbytes(p,l);
|
|
end
|
|
"intarray":
|
|
begin
|
|
ret := _tool.readints(p,l);
|
|
end
|
|
"uintarray":
|
|
begin
|
|
ret := _tool.readuints(p,l);
|
|
end
|
|
"doublearray":
|
|
begin
|
|
ret := _tool.readdoubles(p,l);
|
|
end else
|
|
ret := _objs[v];
|
|
end;
|
|
return ret;
|
|
end
|
|
function _getvalueaddr_(i); //获得值对应的内存地址
|
|
begin
|
|
{**
|
|
@explan(说明)获得值对应的内存地址 %%
|
|
@param(i)() 索引%%
|
|
**}
|
|
return _objs[i];
|
|
end
|
|
|
|
function _getvalueaddr2_(i); //读取值对应地址的值作为地址;
|
|
begin
|
|
{**
|
|
@explan(说明)读取值对应地址的值作为地址 %%
|
|
@param(i)() 索引%%
|
|
**}
|
|
t := _objs[i];
|
|
if ifnumber(t)then
|
|
begin
|
|
return _tool.readptr(t);
|
|
end
|
|
if t is class(ctslctrans)then
|
|
begin
|
|
return t._getptr_();
|
|
end
|
|
end
|
|
function _getdata_();virtual; //获得所有数据
|
|
begin
|
|
{**
|
|
@explan(说明)获得所有数据 %%
|
|
@return(array) %%
|
|
**}
|
|
ret := array();
|
|
for i,v in _objs do
|
|
begin
|
|
if v is class(ctslctrans)then
|
|
begin
|
|
ret[i]:= v._getdata_();
|
|
end else
|
|
ret[i]:= _getvalue_(i);
|
|
end
|
|
return ret;
|
|
end
|
|
function destroy();override; //析构
|
|
begin
|
|
inherited;
|
|
//class(tmemoryclass).destroy();
|
|
_objss := _objst := _objs := array();
|
|
end
|
|
function CopyToString();
|
|
begin
|
|
{**
|
|
@explan(说明)将内存数据转换为字符串%%
|
|
@return(string)
|
|
**}
|
|
r := ""; //binary("");
|
|
ptr := _getptr2_();
|
|
sz := _size_();
|
|
if ptr and sz>0 then
|
|
begin
|
|
setlength(r,sz);
|
|
for i := 0 to sz-1 do r[i+1]:= _tool.readbyte(ptr+i);
|
|
end
|
|
return r;
|
|
end
|
|
function CopyFromString(s);
|
|
begin
|
|
{**
|
|
@explan(说明)将字符串拷贝到内存 %%
|
|
@param(s)(string)
|
|
**}
|
|
ptr := _getptr2_();
|
|
sz := _size_();
|
|
if ifstring(s)and ptr and sz>0 and sz <= length(s)then
|
|
begin
|
|
for i := 0 to sz-1 do
|
|
begin
|
|
_tool.writebyte(ptr+i,ord(s[i+1]));
|
|
end
|
|
end
|
|
end
|
|
end
|
|
type tslcstructureobj=class(ctslctrans) //结构体类
|
|
{**
|
|
@explan(说明)tsl数据结构和内存交互接口类封装
|
|
**}
|
|
(**
|
|
@example(范例--内存结构)
|
|
sc := array(("a","int",1),("b","double",2)("c","intptr",1234));
|
|
//兼容c中的 co = new struct{int a = 1; double b = 2.0; intptr = 1234}
|
|
co := new tslcstructureobj(MemoryAlignmentCalculate(sc));
|
|
co._setvalue_("a",5); //设置成员 a的值
|
|
echo co._getvalue_("b");//获得成员 b 的值
|
|
echo co._size_();//获得内存大小
|
|
echo co._getptr_() ;//对象对应的内存指针
|
|
|
|
**)
|
|
function create(data,ptr);
|
|
begin
|
|
{**
|
|
@explan(说明) 内存对象构造 %%
|
|
@param(data)(array) 内存结构,使用 MemoryAlignmentCalculate 产生 %%
|
|
@param(ptr)(integer|nil) 内存指针,如果不给定,自动分配,如果给定从内存读取 %%
|
|
**}
|
|
//return inherited create(data,ptr,nil);
|
|
class(ctslctrans).create(data,ptr,nil);
|
|
end
|
|
function destroy();override;
|
|
begin
|
|
inherited;
|
|
end
|
|
end
|
|
|
|
//*********字符串相关对象**************************************
|
|
type tcbytearray=class
|
|
reallen;
|
|
len; //长度
|
|
obj; //对象
|
|
{**
|
|
@explan(说明) byte数组内存管理类 %%
|
|
@param(len)(integer) 数组占用长度 %%
|
|
@param(reallen)(integer) 实际内存长度 %%
|
|
@param(obj)(tslcstructureobj) 内存对象%%
|
|
**}
|
|
function create(n);
|
|
begin
|
|
{**
|
|
@explan(说明)构造 %%
|
|
@param(n)(integer|array of integer) 字符串长度 预分配%%
|
|
|
|
**}
|
|
reallen := len := 0;
|
|
if not(n>0)then n := 128;
|
|
setv(n);
|
|
end
|
|
function reset(n);
|
|
begin
|
|
{**
|
|
@explan(说明)重新设置 %%
|
|
@param(n)(array of byte) 设置字的数组%%
|
|
**}
|
|
t := true;
|
|
if ifnumber(n)and n>0 and n>reallen then
|
|
begin
|
|
len := reallen := n;
|
|
obj := new ctslctrans(MemoryAlignmentCalculate(array((0,format("byte[%d]",reallen),array(0))))); //tslcstructure(array((0,format("byte[%d]",reallen),array(0))));
|
|
end else
|
|
if ifarray(n)and length(n)>reallen then
|
|
begin
|
|
len := reallen := length(n);
|
|
obj := new ctslctrans(MemoryAlignmentCalculate(array((0,format("byte[%d]",reallen),n)))); //tslcstructure(array((0,format("byte[%d]",reallen),n)));
|
|
t := false;
|
|
end
|
|
if ifarray(n)and t then
|
|
begin
|
|
len := length(n);
|
|
obj._setvalue_(0,n);
|
|
end else
|
|
if ifnumber(n)and t then len := n;
|
|
end
|
|
function occupancy();
|
|
begin
|
|
{**
|
|
@explan(说明)获取内存占用 %%
|
|
@return(integer) 占用大小
|
|
**}
|
|
return reallen;
|
|
end
|
|
function length(n); //设置长度
|
|
begin
|
|
{**
|
|
@explan(说明)设置长度 或者获取数组的占用长度%%
|
|
@param(n)(integer|nil) nil为获取长度,数字为设置长度 %%
|
|
**}
|
|
if ifnumber(n)then reset(n);
|
|
return len;
|
|
end
|
|
function _getptr_();
|
|
begin
|
|
{**
|
|
@explan(说明)返回数组内存指针 %%
|
|
**}
|
|
return obj._getptr_();
|
|
end
|
|
function setv(n);virtual;
|
|
begin
|
|
{**
|
|
@explan(说明)设置byte数组 %%
|
|
@param(n)(array of byte) 数组%%
|
|
|
|
**}
|
|
return reset(n);
|
|
end
|
|
function getv();
|
|
begin
|
|
{**
|
|
@explan(说明)返回byte数组 %%
|
|
@return(array of byte ) 返回的数组%%
|
|
**}
|
|
if ifobj(obj)then
|
|
begin
|
|
return obj._getvalue_(0);
|
|
end
|
|
end
|
|
function ptr();
|
|
begin
|
|
{**
|
|
@explan(说明)返回内存指针 %%
|
|
**}
|
|
return _getptr_();
|
|
end
|
|
end
|
|
type tcstring=class(tcbytearray)
|
|
{**
|
|
@explan(说明)字符串内存管理类 %%
|
|
@param(_flag)(integer) 字符串是否包含\0结尾%%
|
|
**}
|
|
private
|
|
_flag;
|
|
public
|
|
function create(n);
|
|
begin
|
|
inherited;
|
|
end
|
|
function getv(n);
|
|
begin
|
|
{**
|
|
@explan(说明)返回字符串 %%
|
|
@param(n)(integer)获取字符串的长度 %%
|
|
@return(string) 字符串%%
|
|
**}
|
|
ret := "";
|
|
nhn := not(n);
|
|
v := class(tcbytearray).getv();
|
|
if _flag then
|
|
begin
|
|
for i := 0 to self.length()-2 do
|
|
begin
|
|
vi := v[i];
|
|
if n and i >= n then break;
|
|
ret += chr(v[i]);
|
|
end
|
|
end else
|
|
begin
|
|
for i := 0 to reallen-1 do
|
|
begin
|
|
vi := v[i];
|
|
if(vi=0)and nhn then break;
|
|
if n and i >= n then break;
|
|
ret += chr(v[i]);
|
|
end
|
|
end
|
|
return ret;
|
|
end
|
|
function setv(v);override;
|
|
begin
|
|
{**
|
|
@explan(说明)设置字符串 %%
|
|
@param(v)(string) 字符串%%
|
|
**}
|
|
r := array();
|
|
if ifstring(v)then
|
|
begin
|
|
for i := 1 to length(v) do r[i-1]:= ord(v[i]);
|
|
r[i]:= ord("\0");
|
|
end else
|
|
if ifnumber(v)and v >= 0 then r := v+1;
|
|
else r := 1;
|
|
class(tcbytearray).setv(r);
|
|
end
|
|
property endzero read _flag write _flag;
|
|
{**
|
|
@param(endzero)(bool) 默认为false字符串以\0结束 %%;
|
|
**}
|
|
end
|
|
type tcstructwithcharptr=class(ctslctrans)
|
|
private
|
|
_strso; //字符串对象集合;
|
|
_strn;
|
|
{**
|
|
@explan(说明)内存结构体分配管理类 %%
|
|
@param(_strso)(array of tcstring) 字符串对象集合 %%
|
|
@param(_strn)(array) 字符串长度标记如
|
|
array("str1":"str1len","str2":str2len)表示
|
|
str1,str2两个字段表示字符串
|
|
str1len 和str2len 分别表示两个字符串的最大长度%%
|
|
|
|
**}
|
|
public
|
|
function create(stc,strn1,strn2);
|
|
begin
|
|
{**
|
|
@explan(说明)构造内存对象 %%
|
|
@param(stc)(array) 内存分配结构描述%%
|
|
@param(strn)(array) 字符串所在字段描述%%
|
|
**}
|
|
strn := array();
|
|
if ifarray(strn1)then strn union=strn1;
|
|
if ifarray(strn2)then strn union=strn2;
|
|
for i in strn do //类型清理
|
|
begin
|
|
for j := 0 to length(stc)-1 do
|
|
begin
|
|
if stc[j,0]=i then
|
|
begin
|
|
stc[j,1]:= "intptr";
|
|
end
|
|
end
|
|
end
|
|
class(ctslctrans).create(MemoryAlignmentCalculate(stc),nil,nil);
|
|
if not ifarray(strn)then return;
|
|
_strn := strn;
|
|
_strso := array();
|
|
for i,v in _strn do
|
|
begin
|
|
setstringi(i,v,128);
|
|
end
|
|
for i,v in strn2 do
|
|
begin
|
|
_strso[i].endzero := true;
|
|
end
|
|
end
|
|
function destroy();override;
|
|
begin
|
|
_strso := nil;
|
|
_strn := nil;
|
|
inherited;
|
|
end
|
|
function operator[1](index,v);
|
|
begin
|
|
{**
|
|
@explan(说明) 设置成员 %%
|
|
@param(index)(tslobj) 下标 %%
|
|
@param(v)(tslobj) 值
|
|
**}
|
|
return _setvalue_(index,v);
|
|
end
|
|
function operator[](index);
|
|
begin
|
|
{**
|
|
@explan(说明) 获取成员 %%
|
|
@param(index)(tslobj) 下标 %%
|
|
@return(tslobj) 返回值 %%
|
|
**}
|
|
return _getvalue_(index);
|
|
end
|
|
function _setvalue_(id,v);override;
|
|
begin
|
|
{**
|
|
@explan(说明)设置成员值 %%
|
|
@param(id)(string) 成员id%%
|
|
@param(v)(string|integer) 设置的值%%
|
|
**}
|
|
os := _strso[id];
|
|
if ifobj(os)then
|
|
begin
|
|
cn := _strn[id];
|
|
return setstringi(id,cn,v);
|
|
end
|
|
return inherited;
|
|
end
|
|
function _getvalue_(id,n);override;
|
|
begin
|
|
{**
|
|
@explan(说明)获取成员值 %%
|
|
@param(id)(string) 成员id%%
|
|
@param(n)(integer) 如果为字符串获取字符串的长度,不送入默认为\0结尾%%
|
|
@return(obj) tsl数据%%
|
|
**}
|
|
os := _strso[id];
|
|
if ifobj(os)then return os.getv(n);
|
|
return inherited _getvalue_(id);
|
|
end
|
|
function _getdata_();override;
|
|
begin
|
|
{**
|
|
@explan(说明)获得结构体的值 %%
|
|
@return(array) tsl数据%%
|
|
**}
|
|
r := class(ctslctrans)._getdata_();
|
|
for i,v in _strso do if ifobj(v)then r[i]:= v.getv();
|
|
return r;
|
|
end
|
|
protected
|
|
function setstringi(i,v,n);
|
|
begin
|
|
{**
|
|
@explan(说明)字符串对象分配 %%
|
|
@param(i)(string) 字符串对象的id%%
|
|
@param(v)(string) 字符串对象%%
|
|
@param(n)(string) 字符串所在字段描述%%
|
|
**}
|
|
os := _strso[i];
|
|
if ifnil(os)then
|
|
begin
|
|
os := new tcstring(n);
|
|
end else
|
|
os.setv(n);
|
|
_strso[i]:= os;
|
|
obj := class(ctslctrans);
|
|
if obj._getvalue_(i)<> os.ptr then
|
|
begin
|
|
obj._setvalue_(i,os.ptr);
|
|
end
|
|
if not ifnil(v)then obj._setvalue_(v,os.occupancy()-1); //修改
|
|
end
|
|
end
|
|
|
|
|
|
//c结构体定义类
|
|
type tcstruct= class
|
|
//_tag;
|
|
_size; //大小
|
|
_maxitem; //最大元素
|
|
_name; //名字
|
|
_struct; //内存排布
|
|
static _basetypes; //基础类型
|
|
static _structs; //注册的结构体
|
|
{**
|
|
@ignore 忽略%%
|
|
@explan(说明)c结构体定义类 %%
|
|
@param(_size)(integer) 大小%%
|
|
@param(_maxitem)(integer) 最大元素%%
|
|
@param(_name)(string) 名称%%
|
|
@param(_basetypes)(array) 基础类型表%%
|
|
@param(_structs)(array) 已经注册的结构体%%
|
|
**}
|
|
type typeclass=class
|
|
_st; //开始位置;
|
|
_n; //名称
|
|
_t; //类型名称
|
|
_s; //size;
|
|
_mxi; //最大子项size
|
|
_fa; //数组标记
|
|
_lt; //指针连接次数
|
|
_ltp; //连接的类型
|
|
_ms; //内存空间
|
|
_ot; //原始类型;
|
|
_fb; //是否基础类型
|
|
_stc; //结构
|
|
_plen; //指针分配长度
|
|
_wlen; //写的长度;
|
|
_oot; //原始字符串类型;
|
|
{**
|
|
@explan(说明)类型定义 %%
|
|
@param(_st)(integer) 开始位置%%
|
|
@param(_t)(string) 名称%%
|
|
@param(_mxi)(integer) 最大子项size%%
|
|
@param(_s)(integer) 大小%%
|
|
@param(_fa)(integer) 数组标记%%
|
|
@param(_lt)(integer) 指针连接次数%%
|
|
@param(_ltp)(string) 连接的类型%%
|
|
@param(_ms)(integer) 内存空间%%
|
|
@param(_ot)(string) 原始类型%%
|
|
@param(_fb)(integer) 是否基础类型%%
|
|
@param(_fb)(integer) 是否基础类型%%
|
|
@param(_stc)(tcstruct) 结构%%
|
|
@param(_plen)(integer) 指针分配长度%%
|
|
@param(_wlen)(integer) 写的长度%%
|
|
@param(_oot)(string) 原始字符串类型%%
|
|
**}
|
|
function show(i);
|
|
begin
|
|
{**
|
|
@explan(说明)展示 %%
|
|
@param(i)(integer) 展示标记%%
|
|
**}
|
|
if ifnil(i)then echo "\r\n字段,\t类型\t原型\t位置\t大小\t内存\t数组\t指针\t指向\t基类\t长度";
|
|
echo "\r\n",_n,"\t",_t,"\t",_ot,"\t",_st,"\t",_s,"\t",_ms,"\t",_fa,"\t",_lt,"\t",_ltp,"\t",_fb,"\t",_plen;
|
|
end
|
|
function destroy();
|
|
begin
|
|
_stc := nil;
|
|
end
|
|
function copy(); //对象复制
|
|
begin
|
|
{**
|
|
@explan(说明)对象复制 %%
|
|
**}
|
|
o := new typeclass();
|
|
o._st := _st;
|
|
o._n := _n;
|
|
o._t := _t;
|
|
o._s := _s;
|
|
o._mxi := _mxi;
|
|
o._fa := _fa;
|
|
o._lt := _lt;
|
|
o._ltp := _ltp;
|
|
o._ms := _ms;
|
|
o._ot := _ot;
|
|
o._fb := _fb;
|
|
o._wlen := _wlen;
|
|
o._plen := _plen;
|
|
o._oot := _oot;
|
|
if _stc is class(tcstruct)then
|
|
begin
|
|
o._stc := _stc.copy();
|
|
end
|
|
return o;
|
|
end
|
|
end
|
|
function create(name,data,alim,fr);
|
|
begin
|
|
{**
|
|
@explan(说明)构造 %%
|
|
@param(name)(string) 名称%%
|
|
@param(data)(array) 内存分配%%
|
|
@param(alim)(integer) 对其方式%%
|
|
@param(fr)(integer) 类型判别%%
|
|
**}
|
|
_sinit_();
|
|
if ifnil(name)then return;
|
|
if ifarray(name)then
|
|
begin
|
|
_name := name[0];
|
|
_size := name[1];
|
|
_maxitem := name[1];
|
|
return 1;
|
|
end
|
|
if ifstring(name)then
|
|
begin
|
|
if pos("*,",name)=length(name)then raise "注册类体不能以*结尾";
|
|
_name := name;
|
|
end else
|
|
raise "类型名称错误";
|
|
if ifobj(_structs[name])and not(fr)then raise(name+"类型已经注册");
|
|
ssize := 0;
|
|
tslarraytocstructcalcs(data,alim,ssize,maxitem);
|
|
if ifarray(data)and ssize>0 then
|
|
begin
|
|
_size := ssize;
|
|
_struct := data;
|
|
_maxitem := maxitem;
|
|
_structs[_name]:= self;
|
|
end
|
|
end
|
|
function hasstc(); //将结构hash化
|
|
begin
|
|
{**
|
|
@explan(说明)将结构hash化 %%
|
|
**}
|
|
ret := array();
|
|
for i,v in _struct do
|
|
begin
|
|
ret[v["n"]]:= v["tfo"];
|
|
end
|
|
return ret;
|
|
end
|
|
function findstruct(n); //结构体查找
|
|
begin
|
|
{**
|
|
@explan(说明)结构体查找 %%
|
|
@param(n)(string) 名称%%
|
|
**}
|
|
ov := new typeclass();
|
|
typedeal(n,ov);
|
|
return ov;
|
|
end
|
|
function copy();
|
|
begin
|
|
{**
|
|
@explan(说明)对象复制 %%
|
|
**}
|
|
o := new tcstruct();
|
|
o._name := _name;
|
|
o._size := _size;
|
|
o._maxitem := _maxitem;
|
|
s := array();
|
|
for i,v in _struct do
|
|
begin
|
|
s[i]:= v;
|
|
s[i]["tfo"]:= v["tfo"].copy();
|
|
end
|
|
o._struct := s;
|
|
return o;
|
|
end
|
|
function show();
|
|
begin
|
|
{**
|
|
@explan(说明)展示 %%
|
|
**}
|
|
echo "\r\n名称:",_name;
|
|
echo "\r\n内存大小:",_size;
|
|
echo "\r\n最大成员:",_maxitem;
|
|
echo "\r\n内存分布:"; //,tostn(_struct);
|
|
echo "\r\n字段,\t类型\t原型\t位置\t大小\t内存\t数组\t指针\t指向\t基类\t长度";
|
|
for i,v in _struct do
|
|
begin
|
|
o := v["tfo"];
|
|
o.show(1);
|
|
end
|
|
end
|
|
class function getptrchain(vt_,ret); //获得指针链条
|
|
begin
|
|
{**
|
|
@explan(说明)获得指针链条 %%
|
|
@param(vt_)(string) 名称%%
|
|
@param(ret)() 返回%%
|
|
**}
|
|
vt := vt_;
|
|
ret := 0;
|
|
while(vt[length(vt)]="*") do
|
|
begin
|
|
ret += 1;
|
|
vt := vt[1:length(vt)-1];
|
|
end
|
|
return vt;
|
|
end
|
|
class function setpptrchain(vt,n); //构造指针连
|
|
begin
|
|
{**
|
|
@explan(说明)获得指针链条 %%
|
|
@param(n)(integer) 指针次数%%
|
|
@param(vt)(string) 类型名称%%
|
|
**}
|
|
ret := vt;
|
|
for i := 1 to n do
|
|
begin
|
|
ret += "*";
|
|
end
|
|
return ret;
|
|
end
|
|
function typedeal(vt,ov,pt); //数组指针处理 char*[5] 表示5个指字符串
|
|
begin
|
|
{**
|
|
@explan(说明)数组指针处理 char*[5] 表示5个指字符串 %%
|
|
**}
|
|
ov._oot := vt;
|
|
if not ifobj(ov)then raise "类型判断参数错误";
|
|
{ctrl := "\\w+[*]*";
|
|
ParseRegExpr(ctrl,vt,"",result,MPos,Mlen);
|
|
if length(result)>2 then raise "类型错误";
|
|
vt_ := result[0,0];
|
|
len := result[1,0];//大小
|
|
ov._ot := vt_; //原型
|
|
if len then //数组标记
|
|
begin
|
|
sz := strtoint(len);
|
|
end
|
|
else
|
|
begin
|
|
sz := 0;
|
|
end }
|
|
parserctypestr(vt,vt_,len);
|
|
if len then sz := len;
|
|
else sz := 0;
|
|
pt := 0;
|
|
vt := getptrchain(vt_,pt);
|
|
ot := _structs[vt];
|
|
if ifobj(ot)then //判断类型是否已经注册
|
|
begin
|
|
o := ot;
|
|
if pt then //指针
|
|
begin
|
|
o := _structs["pointer"];
|
|
if sz>0 then
|
|
begin
|
|
vt := setpptrchain(vt,pt);
|
|
ov._ot := vt;
|
|
end else
|
|
begin
|
|
vt := setpptrchain(vt,pt-1);
|
|
ov._ot := vt;
|
|
end
|
|
ov._lt := pt;
|
|
ov._ltp := vt;
|
|
end
|
|
ov._s := o._size; //尺寸
|
|
ov._mxi := o._maxitem; //最大子元素
|
|
ov._t := o._name; //名称
|
|
ov._fa := sz; //数组标记
|
|
ov._fb := _basetypes[ov._ot]; //原型是否为基础类型;
|
|
_stc := _structs[ov._ot];
|
|
if ifnil(_stc)then ov._stc := o.copy();
|
|
else ov._stc := _stc.copy();
|
|
end else
|
|
raise "类型不存在";
|
|
return ret;
|
|
end
|
|
function tslarraytocstructcalcs(data,alim,ssize,maxitem); //计算对其长度
|
|
begin
|
|
{**
|
|
@explan(说明)计算对其长度 %%
|
|
|
|
**}
|
|
if not ifnumber(alim)then
|
|
begin
|
|
{$ifdef linux}
|
|
alim := 4;
|
|
{$else}
|
|
alim := 8;
|
|
{$endif}
|
|
end
|
|
fmaxitem := function(d,alim) //计算对其长度
|
|
begin
|
|
ret := array();
|
|
for i,v in d do
|
|
begin
|
|
vt := v["t"];
|
|
vo := v["tfo"];
|
|
typedeal(vt,vo);
|
|
end
|
|
return ret;
|
|
end;
|
|
preddata := function(data)
|
|
begin
|
|
if not ifarray(data)then return-1;
|
|
cols := array(0,1,mcols(data,1))->(mcols(data)-1);
|
|
masthave := array("n","t");
|
|
for i,v in masthave do
|
|
begin
|
|
if ifnil(cols[v])then return-1;
|
|
end
|
|
for i := 0 to length(data)-1 do
|
|
begin
|
|
data[i,"tfo"]:= new typeclass();
|
|
end
|
|
end
|
|
if call(preddata,data)=-1 then raise functionname()+"结构体数据错误!";
|
|
npoint := 0; //开始位置
|
|
names := data[:,"n"];
|
|
len1 := length(names);
|
|
if(len1>length(names union2 array()))then raise functionname()+"结构体变量名重复";
|
|
call(fmaxitem,data,alim); //对其长度
|
|
maxitem := 0;
|
|
for i,vi in data do
|
|
begin
|
|
name := vi["n"]; //变量名
|
|
ot := vi["tfo"]; //对象
|
|
ot._n := name;
|
|
len := size := ot._fa; //数组
|
|
tpbyte := ot._s; //当前占用的字节
|
|
if maxitem<ot._mxi then maxitem := ot._mxi;
|
|
if not size then size := 1;
|
|
sz := tpbyte * size; //数据大小
|
|
dp1 := min(alim,ot._mxi);
|
|
npoint := ceil(npoint/dp1)* dp1;
|
|
ot._st := npoint; //元素开始的地址
|
|
ot._ms := sz; //元素占用空间
|
|
npoint += sz;
|
|
end;
|
|
alimlen := min(alim,maxitem);
|
|
ssize :=(ceil(npoint/alimlen)* alimlen);
|
|
ot._ms := ssize-ot._st;
|
|
end
|
|
class function _sinit_(); //初始化
|
|
begin
|
|
{**
|
|
@explan(说明)初始化 %%
|
|
|
|
**}
|
|
if ifnil(_structs)then
|
|
begin
|
|
_structs := array();
|
|
_basetypes := array();
|
|
for i,v in getctypesize() do
|
|
begin
|
|
if i="char*" then continue;
|
|
_structs[i]:= new tcstruct(array(i,v));
|
|
if i="pointer" then continue;
|
|
_basetypes[i]:= true;
|
|
end
|
|
end
|
|
end
|
|
class function getstruct(name);
|
|
begin
|
|
{**
|
|
@explan(说明)获得结构体 %%
|
|
@param(name)(string) 类型名称%%
|
|
**}
|
|
return _structs[name];
|
|
end
|
|
function getsteps(n,ptr);
|
|
begin
|
|
{**
|
|
@explan(说明)内存位置移动 %%
|
|
@param(n)(integer) 移动个数%%
|
|
@param(ptr)(integer) 基准位置%%
|
|
**}
|
|
if ifnumber(n)and ifnumber(_size)then ret := n * _size;
|
|
if ifnumber(ptr)then ret := ptr+_size;
|
|
return ret;
|
|
end
|
|
|
|
end
|
|
//新的内存管理类
|
|
type tcpointer=class(tcstruct,tmemoryclass)
|
|
(**
|
|
@ignore 忽略%%
|
|
@example(范例--内存管理--2)
|
|
//tsl定义
|
|
ts3 := ctypedefine("ts3",array(("n":"a","t":"char[3]"),("n":"b","t":"double")));
|
|
ts2 := ctypedefine("ts2",array(("n":"a","t":"char[5]"),("n":"b","t":"int[3]"),("n":"e","t":"ts3"),("n":"c","t":"ts3*")));
|
|
ts1 := ctypedefine("ts1",array(("n":"a","t":"char[3]"),("n":"m1","t":"ts2")));
|
|
//构造c对应结构体指针,第一个参数为类名称,第二个为初始值
|
|
o := new tcpointer("ts1",array(
|
|
"a":"ab",
|
|
"m1":array(
|
|
"a":"ef",
|
|
"b":array(2,3),
|
|
"e":array(
|
|
"a":"e",
|
|
"b":3
|
|
)
|
|
,
|
|
"c":array(//注意此处指针必须按照数组的形式
|
|
array(
|
|
"a":"w",
|
|
"b":1.5
|
|
),
|
|
array(
|
|
"a":"tt",
|
|
"b":5
|
|
)
|
|
)
|
|
)
|
|
));
|
|
使用ctypedefine 定义和c交互的内存结构
|
|
new tcpointer(定义的类型,初始值) 管理内存对象
|
|
o.getindexi(i) 如果为数组或者指针返回第i个数据
|
|
o._getdata_() 获得结构体中的所有数据已一个数组形式返回
|
|
o._getvalue_("a") 根据索引获得数据
|
|
o._setvalue_("a","ab") 赋值只能是基础类型,对于复杂类型可以按层级赋值,取值
|
|
例如:
|
|
o._getvalue_("m1")._setvalue_("a","f");
|
|
echo tostn(o._getvalue_("m1")._getvalue_("c").getindexi(0)._getdata_);
|
|
echo tostn(o._getvalue_("m1")._getvalue_("c").getindexi(1)._getdata_);
|
|
**)
|
|
_ptr; //指针
|
|
_desc; //描述
|
|
_stc; //内存结构
|
|
_hashstrc; //结构hash
|
|
_fpa; //数组标记;
|
|
_subobj; //子对象
|
|
function create(sn,ivalue,ptr); //sn 名字,ivalue初始值,ptr 指针
|
|
begin
|
|
//初始值
|
|
class(tcstruct).create(); //类型获得
|
|
class(tmemoryclass).create(); //内存操作对象
|
|
mtool();
|
|
_subobj := array();
|
|
if ifobj(sn)then //不变
|
|
begin
|
|
_desc := sn;
|
|
end else
|
|
begin
|
|
_desc := findstruct(sn); //类型描述
|
|
_desc._st := 0;
|
|
_desc._ms := _desc._s; //内存大小描述
|
|
end
|
|
if _desc._fa then _fpa := "a"; //数组
|
|
else if _desc._lt then _fpa := "p";
|
|
_stc := _desc._stc; //结构体描述
|
|
_hashstrc := _stc.hasstc(); //便于查找的hash
|
|
if ptr and ifnumber(ptr)then
|
|
begin
|
|
_ptr := ptr;
|
|
end
|
|
//if ifnil(ivalue) then return ;//没有初始值返回
|
|
if _fpa="a" then //数组
|
|
begin
|
|
sz := _stc.getsteps(_desc._fa); //获得数组的分配空间
|
|
n := _desc._t; //类型
|
|
if not(_ptr)then //内存分配
|
|
_ptr := tmalloc(sz,1);
|
|
if _desc._fb then //基础类型
|
|
begin
|
|
if ifstring(ivalue)and n="char" then
|
|
begin
|
|
_write_(_ptr,n,ivalue,sz-1);
|
|
_desc._wlen := length(ivalue)+1;
|
|
end
|
|
if ifarray(ivalue)and n <> "char" then
|
|
begin
|
|
_write_(_ptr,n+"array",ivalue,length(ivalue));
|
|
_desc._wlen := length(ivalue);
|
|
end
|
|
end else
|
|
begin
|
|
for i,v in ivalue do
|
|
begin
|
|
if i=_desc._fa then break;
|
|
n := _desc._ot;
|
|
_subobj[i]:= new tcpointer(n,v,_ptr+_stc.getsteps(i));
|
|
end
|
|
end
|
|
end else
|
|
if _fpa="p" then //指针
|
|
begin
|
|
if ifnumber(ivalue)then
|
|
begin
|
|
len := ivalue;
|
|
_desc._plen := len;
|
|
sz := _stc.getsteps(len);
|
|
if not(_ptr)then _ptr := tmalloc(sz,1);
|
|
end else
|
|
if ifarray(ivalue)then
|
|
begin
|
|
if _desc._ot="char" then raise "指针类型和赋值不符合";
|
|
len := length(ivalue);
|
|
_desc._plen := len;
|
|
sz := _stc.getsteps(len);
|
|
if not(_ptr)then _ptr := tmalloc(sz,1);
|
|
if _desc._fb then //基础类型
|
|
begin
|
|
_write_(_ptr,_desc._ot+"array",ivalue,len);
|
|
_desc._wlen := len;
|
|
end else
|
|
begin
|
|
for j,sv in ivalue do
|
|
begin
|
|
o := new tcpointer(_desc._ltp,sv,_ptr+_stc.getsteps(j));
|
|
_subobj[j]:= o;
|
|
end
|
|
end
|
|
end else
|
|
if ifstring(ivalue)then
|
|
begin
|
|
if _desc._ot <> "char" then raise "字符串类型赋值错误";
|
|
len := length(ivalue)+1;
|
|
_desc._plen := len;
|
|
sz := len;
|
|
if not(_ptr)then _ptr := tmalloc(sz,1);
|
|
_tool.writestr(_ptr,ivalue);
|
|
_desc._wlen := len;
|
|
end
|
|
end else //普通类型
|
|
begin
|
|
if not(_ptr)then _ptr := tmalloc(_desc._s,1);
|
|
for i,v in ivalue do
|
|
begin
|
|
si := _hashstrc[i];
|
|
if ifobj(si)then
|
|
begin
|
|
ptr := _ptr+si._st; //位置
|
|
n := si._t;
|
|
if si._fa>0 then //数组
|
|
begin
|
|
_subobj[i]:= new tcpointer(si,v,ptr);
|
|
end else
|
|
if si._lt>0 then //指针
|
|
begin
|
|
o := new tcpointer(si,v);
|
|
_subobj[i]:= o;
|
|
_tool.writeptr(ptr,o._ptr);
|
|
end else //普通类型
|
|
begin
|
|
if si._fb then
|
|
begin
|
|
_write_(ptr,n,v);
|
|
end else
|
|
begin
|
|
_subobj[i]:= new tcpointer(si,v,ptr);
|
|
end
|
|
end
|
|
end else
|
|
raise "赋值下标错误";
|
|
end
|
|
end
|
|
end
|
|
function _getptr2_();
|
|
begin
|
|
{**
|
|
@explan(说明) 获取内存地址 %%
|
|
**}
|
|
x := 0;
|
|
for i,v in _objstart do
|
|
begin
|
|
x := v;
|
|
break;
|
|
end
|
|
return _getptr_()+x;
|
|
end
|
|
function _getptr_(); //获得地址
|
|
begin
|
|
return _ptr;
|
|
end
|
|
function _size_(); //获得对象占用空间大小
|
|
begin
|
|
siz := _desc._size;
|
|
if _desc._fa then siz *= _desc._fa;
|
|
return siz;
|
|
end
|
|
function _getvalueaddr_(i); //获得值对应的内存地址
|
|
begin
|
|
if ifnil(i)then return _ptr;
|
|
tv := _hashstrc[i];
|
|
if ifobj(tv)then
|
|
begin
|
|
return _ptr+tv._st; //元素地址
|
|
end
|
|
end
|
|
function _setcptr_(ptr); //设置对象地址
|
|
begin
|
|
if ifnumber(ptr)and ptr then _ptr := ptr;
|
|
end
|
|
function _read_(p,t,l); //基本类型读取
|
|
begin
|
|
case t of
|
|
"char":
|
|
begin
|
|
ret := _tool.readstr(p);
|
|
end
|
|
"int":
|
|
begin
|
|
ret := _tool.readint(p);
|
|
end
|
|
"intptr":
|
|
begin
|
|
ret := _tool.readptr(p);
|
|
end
|
|
"double":
|
|
begin
|
|
ret := _tool.readdouble(p);
|
|
end
|
|
"float":
|
|
begin
|
|
ret := _tool.readfloat(p);
|
|
end
|
|
"byte":
|
|
begin
|
|
ret := _tool.readbyte(p);
|
|
end
|
|
"short":
|
|
begin
|
|
ret := _tool.readshort(p);
|
|
end
|
|
"bytearray":
|
|
begin
|
|
ret := _tool.readbytes(p,l);
|
|
end
|
|
"intarray":
|
|
begin
|
|
ret := _tool.readints(p,l);
|
|
end
|
|
"doublearray":
|
|
begin
|
|
ret := _tool.readdoubles(p,l);
|
|
end
|
|
end;
|
|
return ret;
|
|
end
|
|
function _write_(p,t,v,l); //基本类型写入
|
|
begin
|
|
case t of
|
|
"char":
|
|
begin
|
|
if ifstring(v)then
|
|
begin
|
|
if ifnumber(l)and length(v)>l then
|
|
begin
|
|
//echo "\r\nstringwrite:",l,"****",length(v);
|
|
return-1;
|
|
end
|
|
_tool.writestr(p,v);
|
|
ret := 1;
|
|
end
|
|
end
|
|
"int":
|
|
begin
|
|
if ifnumber(v)then
|
|
begin
|
|
_tool.writeint(p,v);
|
|
ret := 1;
|
|
end
|
|
end
|
|
"intptr":
|
|
begin
|
|
if ifnumber(v)then
|
|
begin
|
|
_tool.writeptr(p,v);
|
|
ret := 1;
|
|
end
|
|
ret := 1;
|
|
end
|
|
"double":
|
|
begin
|
|
if ifnumber(v)then
|
|
begin
|
|
_tool.writedouble(p,v);
|
|
ret := 1;
|
|
end
|
|
end
|
|
"float":
|
|
begin
|
|
if ifnumber(v)then
|
|
begin
|
|
_tool.writefloat(p,v);
|
|
ret := 1;
|
|
end
|
|
end
|
|
"byte":
|
|
begin
|
|
if ifnumber(v)then
|
|
begin
|
|
_tool.writebyte(p,v);
|
|
ret := 1;
|
|
end
|
|
end
|
|
"short":
|
|
begin
|
|
if ifnumber(v)then
|
|
begin
|
|
_tool.writeshort(p,v);
|
|
ret := 1;
|
|
end
|
|
end
|
|
"bytearray":
|
|
begin
|
|
_tool.writebytes(p,min(length(v),l),v);
|
|
ret := true;
|
|
end
|
|
"intarray":
|
|
begin
|
|
_tool.writeints(p,min(length(v),l),v);
|
|
ret := true;
|
|
end
|
|
"doublearray":
|
|
begin
|
|
_tool.writedoubles(p,min(length(v),l),v);
|
|
ret := true;
|
|
end
|
|
end;
|
|
return ret;
|
|
end
|
|
function _getdata_(); //获得所有的数据
|
|
begin
|
|
t := _desc._ot;
|
|
fp := _fpa;
|
|
if fp="a" then
|
|
begin
|
|
if _desc._fb then
|
|
begin
|
|
if t="char" then
|
|
begin
|
|
//echo "\r\nreade:",_ptr;
|
|
v := _tool.readstr(_ptr);
|
|
//echo "readv:" ,v,datatype(v);
|
|
return v;
|
|
end else
|
|
begin
|
|
return _read_(_ptr,t+"array",_desc._fa);
|
|
end
|
|
end else
|
|
begin
|
|
ret := array();
|
|
for i := 0 to _desc._fa-1 do
|
|
begin
|
|
ret[i]:= getindexi(i)._getdata_();
|
|
end
|
|
return ret;
|
|
end
|
|
end else
|
|
if fp="p" then
|
|
begin
|
|
t := _desc._ot;
|
|
if _desc._fb then
|
|
begin
|
|
if t="char" then
|
|
begin
|
|
return _tool.readstr(_ptr);
|
|
end else
|
|
begin
|
|
return _read_(_ptr,t+"array",_desc._plen);
|
|
end
|
|
end else
|
|
begin
|
|
ret := array();
|
|
if ifnumber(_desc._plen)then
|
|
begin
|
|
for i := 0 to _desc._plen-1 do
|
|
begin
|
|
ret[i]:= getindexi(i)._getdata_();
|
|
end
|
|
end
|
|
return ret;
|
|
end
|
|
end else
|
|
begin
|
|
ret := array();
|
|
for i,v in _hashstrc do
|
|
begin
|
|
n := v._n;
|
|
o := _getvalue_(n);
|
|
if ifobj(o)then ret[n]:= o._getdata_();
|
|
else ret[n]:= o;
|
|
end
|
|
return ret;
|
|
end
|
|
end
|
|
function getindexi(i); //获得数组或者指针第i个元素,基础类型返回值,复杂类型返回对象
|
|
begin
|
|
if(_fpa="a" and i >= 0 and i<_desc._fa)then //
|
|
begin
|
|
//基础类型
|
|
ret := _subobj[i];
|
|
if ifobj(ret)then return ret;
|
|
psi :=(_desc._s * i+_ptr);
|
|
if not(_desc._fb)then //非基础类型
|
|
begin
|
|
return new tcpointer(_desc._t,nil,psi);
|
|
end else //基础类型
|
|
begin
|
|
if _desc._t <> "char" then
|
|
begin
|
|
return _read_(psi,_desc._ot);
|
|
end
|
|
end
|
|
end else
|
|
if _desc._lt>0 and i >= 0 then
|
|
begin
|
|
ret := _subobj[i];
|
|
if ifobj(ret)then return ret;
|
|
ps := _ptr;
|
|
if ps=0 then return nil;
|
|
if _desc._lt>1 then
|
|
begin
|
|
psi :=(ps+_desc._ms * i);
|
|
o := new tcpointer(_desc._ot,nil,psi);
|
|
_subobj[i]:= o;
|
|
return o;
|
|
end else
|
|
begin
|
|
psi := ps+(_desc._stc._size * i);
|
|
if not(_desc._fb)then //非基础类型
|
|
begin
|
|
o := new tcpointer(_desc._ot,nil,psi);
|
|
_subobj[i]:= o;
|
|
return o;
|
|
end else //基础类型
|
|
begin
|
|
if _desc._ot <> "char" then
|
|
begin
|
|
return _read_(psi,_desc._ot);
|
|
end else
|
|
return _read_(psi,"char");
|
|
end
|
|
end
|
|
end
|
|
end
|
|
function _setvalue_(i,v); //给下标字段设置值,只支持基础类型
|
|
begin
|
|
if ifnil(i)then
|
|
begin
|
|
ds := _desc;
|
|
//ds.show();
|
|
end else
|
|
ds := _hashstrc[i];
|
|
if not ifobj(ds)then return nil;
|
|
ptr := _ptr+ds._st;
|
|
if ds._fb then //基础类型
|
|
begin
|
|
if not(ds._fa or ds._lt)then //非数组或者指针
|
|
begin
|
|
_write_(ptr,ds._t,v);
|
|
end else
|
|
if ds._fa then
|
|
begin
|
|
if ds._ot="char" and ifstring(v)then
|
|
begin
|
|
_write_(ptr,ds._ot,v,ds._fa);
|
|
end else
|
|
if ds._ot <> "char" and ifarray(v)then
|
|
begin
|
|
_write_(ptr,ds._ot+"array",v,ds._fa);
|
|
end
|
|
end else
|
|
if ds._lt then //指针
|
|
begin
|
|
if(v is class(tcpointer))then //设置值
|
|
begin
|
|
if(ds._ot=v._desc._ot)and(ds._lt=v._desc._lt)then
|
|
begin
|
|
begin
|
|
_subobj[i]:= v;
|
|
_write_(ptr,"intptr",v._ptr);
|
|
end
|
|
end
|
|
return;
|
|
end
|
|
ptr := _read_(ptr,"intptr");
|
|
if ptr then
|
|
begin
|
|
if ds._ot="char" and ifstring(v)and(length(v)<ds._plen or ifnil(ds._plen))then
|
|
begin
|
|
_write_(ptr,ds._ot,v);
|
|
end else
|
|
if ds._ot <> "char" and ifarray(v)then
|
|
begin
|
|
_write_(ptr,ds._ot+"array",v,ifnumber(ds._plen)?(ds._plen):(length(v)));
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
function _getvalue_(i,L); //获取值,支持基础类型,i为下标,l在为指针的时候指定长度
|
|
begin
|
|
v := _hashstrc[i];
|
|
if not ifobj(v)then return nil;
|
|
ptr := _ptr+v._st;
|
|
t := v._ot;
|
|
if v._fb then //基础类型
|
|
begin
|
|
if v._fa then
|
|
begin
|
|
if v._ot="char" then return _read_(ptr,"char");
|
|
return _read_(ptr,v._ot+"array",ifnumber(L)?min(v._fa,L):v._fa);
|
|
end else
|
|
if v._lt then
|
|
begin
|
|
ptr := _read_(ptr,"intptr");
|
|
if ptr <> 0 then
|
|
begin
|
|
if v._ot="char" then return _read_(ptr,"char");
|
|
return _read_(ptr,v._ot+"array",ifnumber(L)?L:v._plen);
|
|
end
|
|
end else
|
|
begin
|
|
return _read_(ptr,v._ot);
|
|
end
|
|
end else
|
|
begin
|
|
if not ifobj(_subobj[i])then
|
|
begin
|
|
if v._fa then //数值
|
|
begin
|
|
_subobj[i]:= new tcpointer(v,nil,ptr);
|
|
end else
|
|
if v._lt then //指针
|
|
begin
|
|
ptr := _read_(ptr,"intptr");
|
|
if ptr <> 0 then
|
|
begin
|
|
_subobj[i]:= new tcpointer(v,nil,ptr);
|
|
end
|
|
end else
|
|
begin
|
|
//echo v.show;
|
|
_subobj[i]:= new tcpointer(v,nil,ptr);
|
|
end
|
|
end
|
|
return _subobj[i];
|
|
end
|
|
end
|
|
function destroy(); //析构
|
|
begin
|
|
_subobj := array();
|
|
class(tmemoryclass).destroy();
|
|
end
|
|
function activefree(); //主动析构,目前不完善,需要等结构体调整好后补充
|
|
begin
|
|
if _desc._lt then activefreesub(ptr_);
|
|
end
|
|
protected
|
|
function activefreesub(ptr_);
|
|
begin
|
|
ptr := opblocks(ptr_,0);
|
|
if ifnil(ptr)then
|
|
begin
|
|
_tool.tfree(ptr_);
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
Implementation
|
|
function ReadStringFromPtr(ptr);
|
|
begin
|
|
{**
|
|
@explan(说明) 读取一个指向\0字符串指针的值 %%
|
|
@param(ptr)(pointer) 指针 %%;
|
|
@return(string) 字符串 %%
|
|
|
|
**}
|
|
if ptr and ifnumber(ptr)then return getmemtool().readstr(ptr);
|
|
return "";
|
|
end
|
|
function WriteStringToPtr(ptr,str);
|
|
begin
|
|
{**
|
|
@explan(说明) 向一个指针写入\0结尾的字符串 %%
|
|
@param(ptr)(pointer) 指针 %%;
|
|
@param(str)(string) 字符串 %%
|
|
**}
|
|
if ifnumber(ptr)and ifstring(str)and ptr then return getmemtool().writestr(ptr,str);
|
|
return 0;
|
|
end
|
|
function ReadBytesFromPtr(ptr,L);
|
|
begin
|
|
{**
|
|
@explan(说明) 读取一个指向数组指针的值 %%
|
|
@param(ptr)(pointer) 指针 %%;
|
|
@param(L)(integer) 长度 %%;
|
|
@return(array of integer) 字符串 %%
|
|
**}
|
|
if ptr and ifnumber(ptr)and L>0 then return getmemtool().readbytes(ptr,L);
|
|
end
|
|
function WriteBytesToPtr(ptr,bytes);
|
|
begin
|
|
{**
|
|
@explan(说明) 向一个指针写入字节数据 %%
|
|
@param(ptr)(pointer) 指针 %%;
|
|
@param(bytes)(array of integer) 数据 %%
|
|
**}
|
|
if ifnumber(ptr)and ptr and ifarray(bytes)then return getmemtool().writebytes(ptr,length(bytes),bytes);
|
|
return 0;
|
|
end
|
|
function getmemtool();
|
|
begin
|
|
return static new aefclassobj_();
|
|
end
|
|
function MemoryAlignmentCalculate(data,baselen,ssize,pack);
|
|
begin
|
|
{**
|
|
@explan(说明) 结构体排布计算 %%
|
|
@param(data)(array) 结构体信息数组,参考 cstructurelib中 tslarraytocstructcalc %%
|
|
@param(baselen)(integer) 基准位置默认为0 %%
|
|
@param(ssize)(integer) 大小 %%
|
|
@param(pack)(integer) 对其方式 windows 默认8 linux 默认4 %%
|
|
**}
|
|
if not ifnumber(baselen)then baselen := 1; //最小长度
|
|
if not ifnumber(ssize)then ssize := 0; //大小
|
|
if not ifnumber(pack)then
|
|
begin
|
|
{$ifdef linux}
|
|
pack := 4;
|
|
{$else}
|
|
pack := 8; //对齐
|
|
{$endif}
|
|
end
|
|
//return tslcstructure_calc(data,baselen,ssize,pack);
|
|
return tslarraytocstructcalc(data,pack,0,ssize);
|
|
end
|
|
function ctypedefine(name,stc,alim,f); //结构体定义
|
|
begin
|
|
{**
|
|
@explan(说明)结构体定义 %%
|
|
@param(name)(string) 名称 %%
|
|
@param(stc)(array) 内存分布 %%
|
|
@param(alim)(integer) 对其方式 %%
|
|
@return(tcstruct)
|
|
**}
|
|
return new tcstruct(name,stc,alim,f);
|
|
end
|
|
function tslarraytocstructcalc(data,alim,bsi,ssize); //计算对其长度
|
|
begin
|
|
{**
|
|
@explan(说明)计算内存对其长度 %%
|
|
@param(data)(array) 数据
|
|
tsl数据结构 二维数组
|
|
每行为c 结构体的一个数据
|
|
0 列为 字符串类型的变量名字
|
|
1 列为 变量类型 ,字符串 (包括 short,short[n],intptr,intptr[n],int,int[n],double,double[n],char[n],byte,byte[n] n为数组大小)
|
|
当类型为char*的时候需要分配内存空间, 第2列为string值 或者是整数 string的长度
|
|
2 列为 值
|
|
%%
|
|
@param(alim)(integer) 对其方式 %%
|
|
@param(bsi)(integer) 基地址,默认为0 %%
|
|
@param(ssize)(array) 结构体大小 %%
|
|
@return(array) 返回值在参数data 增加下面字段
|
|
3 列为 相对偏移
|
|
4 列为 大小
|
|
5 列为 名字
|
|
6 列为 如果为数组表示个数
|
|
**}
|
|
{
|
|
data 数据
|
|
alim 对其
|
|
bsi 基地址 //默认为0
|
|
ssize 结构体大小
|
|
结构体偏移量;和c接口对接
|
|
参数: data tsl数据结构 二维数组
|
|
每行为c 结构体的一个数据
|
|
0 列为 字符串类型的变量名字
|
|
1 列为 变量类型 ,字符串 (包括 short,short[n],intptr,intptr[n],int,int[n],double,double[n],char[n],byte,byte[n] n为数组大小)
|
|
当类型为char*的时候需要分配内存空间, 第2列为string值 或者是整数 string的长度
|
|
2 列为 值
|
|
返回值 增加下面字段
|
|
3 列为 相对偏移
|
|
4 列为 大小
|
|
5 列为 名字
|
|
6 列为 如果为数组表示个数
|
|
baselen 基础长度
|
|
ssize 结构体大小;
|
|
pack //对其方式
|
|
}
|
|
if not ifnumber(alim)then
|
|
begin
|
|
{$ifdef linux}
|
|
alim := 4;
|
|
{$else}
|
|
alim := 8;
|
|
{$endif}
|
|
end
|
|
if not ifnumber(bsi)then bsi := 0;
|
|
fmaxitem := function(d,cl) //计算对其长度
|
|
begin
|
|
ret := array();
|
|
for i,v in d do
|
|
begin
|
|
vt := v[1];
|
|
{ctrl := "\\w+[*]?";
|
|
ParseRegExpr(ctrl,vt,"",result,MPos,Mlen);
|
|
vt := result[0,0];}
|
|
parserctypestr(vt,tt,len);
|
|
vt := tt;
|
|
//echo tt,"\r\n";
|
|
if vt="user" then ret[i]:= maxvalue(call(thisfunction,v[2],cl));
|
|
else ret[i]:= cl[vt];
|
|
end
|
|
return ret;
|
|
end;
|
|
if ifnumber(data)then return data; //如果为整数
|
|
if not ifarray(data)then raise functionname()+"结构体数据错误!";
|
|
if mcols(data)<1 then raise functionname()+"结构体数据错误";
|
|
ret := data; //返回值
|
|
npoint := bsi; //开始位置
|
|
names := data[:,0];
|
|
len1 := length(names);
|
|
if(len1>length(names union2 array()))then raise functionname()+"结构体变量名重复";
|
|
ctypebytes := static getctypesize();
|
|
ctypebytes["user*"]:= ctypebytes["intptr"];
|
|
ctypenames := mrows(ctypebytes,1);
|
|
itemslen := call(fmaxitem,data,ctypebytes); //对其长度
|
|
for i,vi in data do
|
|
begin
|
|
name := vi[0]; //变量名
|
|
tp := vi[1]; //变量类型
|
|
v := vi[2]; //变量值
|
|
ctrl := "\\w+[*]?";
|
|
{ParseRegExpr(ctrl,tp,"",result,MPos,Mlen);
|
|
tp1 := result[0,0]; //类型
|
|
size := result[1,0];//大小
|
|
if ifstring(size) then size := strtoint(size);}
|
|
parserctypestr(tp,tp1,size);
|
|
//echo "*************************",size;
|
|
tpbyte := itemslen[i]; //当前占用的字节
|
|
if(tp1 in array("uint","char","float","double","int","intptr","byte","short","char*","user*"))then
|
|
begin
|
|
tpn := tp1;
|
|
ret[i,5]:= tpn;
|
|
if not(size)then
|
|
begin
|
|
if(tpn in array("char"))then
|
|
begin
|
|
raise "请使用数组形式";
|
|
end;
|
|
size := 1;
|
|
if ifstring(v)then size := length(v)+1;
|
|
end else
|
|
begin
|
|
if ifarray(v)then
|
|
begin
|
|
if length(v)>size then raise "初始值大小超过分配空间";
|
|
end else
|
|
if ifstring(v)then
|
|
begin
|
|
//echo "*********************************************************88";
|
|
//echo size,tostn(v),length(v);
|
|
if length(v)>(size-1)then raise "初始值大小超过分配空间";
|
|
end
|
|
if not(tpn in array("char"))then ret[i,5]+= "array";
|
|
end
|
|
if tp1="char*" then
|
|
begin
|
|
sz := tpbyte;
|
|
end else
|
|
begin
|
|
sz := tpbyte * size; //数据大小
|
|
end
|
|
if(tp1="user*")then //结构体指针
|
|
begin
|
|
ret[i,2]:= tslarraytocstructcalc(v,alim,0,0);
|
|
sz := tpbyte; //元素大小
|
|
end
|
|
dp1 := min(alim,tpbyte);
|
|
npoint := ceil(npoint/dp1)* dp1;
|
|
end else
|
|
if(tp1="user")then
|
|
begin
|
|
ret[i,5]:= "userarray";
|
|
size := 1;
|
|
sz := 0;
|
|
dp1 := min(alim,tpbyte);
|
|
npoint := ceil(npoint/dp1)* dp1;
|
|
ret1 := tslarraytocstructcalc(v,alim,npoint,sz);
|
|
ret[i,2]:= ret1;
|
|
end else
|
|
raise "类型错误";
|
|
ret[i,3]:= npoint; //元素开始的地址
|
|
ret[i,4]:= sz; //元素占用空间
|
|
ret[i,6]:= size; //元素个数
|
|
npoint += sz;
|
|
end
|
|
st := npoint-bsi;
|
|
alimlen := min(alim,maxvalue(itemslen));
|
|
ssize :=(ceil(st/alimlen)* alimlen);
|
|
ret[length(ret)-1,4]+=(ssize-st);
|
|
return ret;
|
|
end
|
|
function parserctypestr(ts,t,s,n);
|
|
begin
|
|
{**
|
|
@explan(说明)类型解析 %%
|
|
@param(ts)(string) 类型字符串 如 "char[100]" %%
|
|
@param(t)(string) 类型 %%
|
|
@param(s)(integer) 数组长度 %%
|
|
@param(n)(string) 名称 %%
|
|
**}
|
|
t := "";
|
|
s := "";
|
|
n := "";
|
|
lx := 1; //解析类型
|
|
len := length(ts);
|
|
i := 1;
|
|
while i <= len do
|
|
begin
|
|
vi := ts[i];
|
|
if vi="[" then //解析数组长度
|
|
begin
|
|
i++;
|
|
while i <= len do
|
|
begin
|
|
vi := ts[i];
|
|
ixvi := ord(vi);
|
|
if vi="]" then //转换长度
|
|
begin
|
|
if s then s := strtoint(s);
|
|
return;
|
|
end else
|
|
if(ixvi >= 48 and ixvi <= 57)then s += vi; //子记录数字符号
|
|
i++;
|
|
end
|
|
return;
|
|
end else
|
|
if vi="*" then
|
|
begin
|
|
t += vi;
|
|
end else
|
|
if(vi="\t" or vi=" ")and lx=1 and t then
|
|
begin
|
|
lx := 2;
|
|
end else
|
|
if not(vi="\t" or vi=" ")then
|
|
begin
|
|
if lx=2 then n += vi;
|
|
else if lx=1 then t += vi;
|
|
end
|
|
i++;
|
|
end
|
|
end
|
|
function addtable(d,n);
|
|
begin
|
|
tbs := "";
|
|
for i := 1 to n do tbs += "\t";
|
|
r := "";
|
|
for i,v in str2array(d,"\r\n") do if v then r += tbs+v+"\r\n";
|
|
return r;
|
|
end
|
|
function cstructtotslclass(data,name,fz);
|
|
begin
|
|
{**
|
|
@explan(说明)将数组结构转换为对象 %%
|
|
**}
|
|
s := format("type %s = class(tslcstructureobj)\r\n",name);
|
|
s += "uses cstructurelib;\r\n";
|
|
s += "private\r\n\tstatic SSTRUCT;\r\n";
|
|
fs := "";
|
|
fp := "";
|
|
sf := "";
|
|
gsf := "";
|
|
intf := format("\tclass function getstruct()\r\n\tbegin\r\n\t\tif not SSTRUCT then SSTRUCT := MemoryAlignmentCalculate(\r\n%s\r\n\t\treturn SSTRUCT;\r\n\tend\r\n",addtable(tostn(data)+");",3));
|
|
if fz then cf2 := "public\r\nclass function memsize();\r\nbegin\r\n\tif not SSTRUCT then getstruct();\r\n\tif SSTRUCT then \r\n\tbegin\r\n\t\tldata := length(SSTRUCT)-1;\r\n\t\treturn SSTRUCT[ldata,3]+SSTRUCT[ldata,4]-SSTRUCT[0,3];\r\n\tend \r\n\treturn 0;\r\nend";
|
|
else cf2 := "";
|
|
cf := "\tpublic\r\n\tfunction create(ptr)\r\n\tbegin\r\n\t\tinherited create(getstruct(),ptr); \r\n\tend\r\n";
|
|
for i,v in data do
|
|
begin
|
|
v0 := v[0];
|
|
//fs += "\tF"+ v[0]+";\r\n";
|
|
fp += format('\tproperty %s index "%s" read _getvalue_ write _setvalue_;\r\n',v0,v0);
|
|
{sf += format("\tfunction Set%s(v)\r\n\tbegin\r\n",v0);
|
|
sf += format("\t\t_setvalue_('%s',v);\r\n",v0,v0,v0);
|
|
sf +="\tend\r\n";
|
|
gsf += format("\tfunction Get%s()\r\n\tbegin\r\n",v0);
|
|
gsf += format("\t\treturn _getvalue_('%s');\r\n",v0);
|
|
gsf +="\tend\r\n";}
|
|
end
|
|
s += gsf;
|
|
s += intf;
|
|
s += sf;
|
|
s += addtable(cf2,1);
|
|
s += cf;
|
|
s += fp;
|
|
s += "end";
|
|
return s;
|
|
end
|
|
//*************删除c注释*****************
|
|
function dealcppcomment(strs)
|
|
begin
|
|
{**
|
|
@explan(说明)删除c语言注释 %%
|
|
@param(strs)(string) c结构体字符串 %%
|
|
@return(string)
|
|
**}
|
|
rets := "";
|
|
len := length(strs);
|
|
i := 1;
|
|
while i<len do
|
|
begin
|
|
ps := strs[i:i+1];
|
|
if ps="//" then
|
|
begin
|
|
i += 2;
|
|
while(true) do
|
|
begin
|
|
if strs[i]="\n" then
|
|
begin
|
|
break;
|
|
end
|
|
i++;
|
|
end
|
|
end else
|
|
if(ps="/*")then
|
|
begin
|
|
i += 2;
|
|
while true do
|
|
begin
|
|
if strs[i:i+1]="*/" then
|
|
begin
|
|
i += 2;
|
|
break;
|
|
end
|
|
i++;
|
|
end
|
|
end
|
|
if i<len then rets += strs[i++];
|
|
end
|
|
return rets;
|
|
end
|
|
//**********c结构体转换到tsl对象*********************************
|
|
function csstotslarray3(ret,iv);
|
|
begin
|
|
{**
|
|
@explan(说明)对c结构定义,初始值 %%
|
|
@param(ret)(array) 结构定义 %%
|
|
@param(iv)(array) 初始值 %%
|
|
@return(array) 结构定义
|
|
**}
|
|
r := array();
|
|
iv := array();
|
|
for i,v in ret do
|
|
begin
|
|
n := ret[i,0];
|
|
r[i]["n"]:= n;
|
|
r[i]["t"]:= ret[i,1];
|
|
iv[n]:= ret[i,2];
|
|
end
|
|
return r;
|
|
end
|
|
function csstotslarray2(csstr1,iv);
|
|
begin
|
|
{**
|
|
@explan(说明)将c的结构体字符串形式转换为tsl数组 %%
|
|
@param(csstr1)(string) c结构体字符串 %%
|
|
@param(iv)(array) 初始值 %%
|
|
@return(array) 结构定义
|
|
**}
|
|
(**
|
|
@example(转换cstruct结构到tslarray-2)
|
|
s := "
|
|
typedef struct _SYSTEMTIME {
|
|
WORD wYear;
|
|
WORD wMonth;
|
|
WORD wDayOfWeek;
|
|
WORD wDay;
|
|
WORD wHour;
|
|
WORD wMinute;
|
|
WORD wSecond;
|
|
WORD wMilliseconds;
|
|
} SYSTEMTIME, *PSYSTEMTIME;
|
|
";
|
|
return csstotslarray2(s);
|
|
**)
|
|
ret := csstotslarray(csstr1);
|
|
return csstotslarray3(ret,iv);
|
|
end
|
|
function csstotslarray(csstr1,tname);
|
|
begin
|
|
{**
|
|
@explan(说明)将c的结构体字符串形式转换为tsl数组 %%
|
|
@param(csstr1)(string) c结构体字符串 %%
|
|
@param(tname)(string) 名称,返回值 %%
|
|
@return(array) 结构定义%%
|
|
**}
|
|
(**
|
|
@example(转换cstruct结构到tslarray-1)
|
|
s := "
|
|
typedef struct tagWINDOWPOS {
|
|
HWND hwnd;
|
|
HWND hwndInsertAfter;
|
|
int x;
|
|
int y;
|
|
int cx;
|
|
int cy;
|
|
UINT flags;
|
|
} WINDOWPOS, *LPWINDOWPOS, *PWINDOWPOS;
|
|
|
|
";
|
|
return csstotslarray(s);
|
|
**)
|
|
typecp := array("int":"int",
|
|
"float":"float",
|
|
"uint":"int",
|
|
"lpstr":"char*",
|
|
"char":"char",
|
|
"char*":"char*",
|
|
"dword":"int",
|
|
"long":"int",
|
|
"byte":"byte",
|
|
"short":"short",
|
|
"word":"short", //byte[2]
|
|
"rect":"int[4]",
|
|
"size":"int[2]",
|
|
"point":"int[2]",
|
|
"double":"double",
|
|
"lpcstr":"char*",
|
|
"bool":"int",
|
|
"colorref":"int",
|
|
"nmhdr":"nmhdr",
|
|
"guid":"guid"
|
|
);
|
|
//类型对应初始值表
|
|
typecv := array(
|
|
"float":0,
|
|
"int":0,
|
|
"char*":100,
|
|
"short":0,
|
|
"byte":0,
|
|
"int[4]":array(0,0,0,0),
|
|
"int[2]":array(0,0),
|
|
"byte[2]":array(0,0),
|
|
"double":0,
|
|
"intptr":0,
|
|
"nmhdr":array(
|
|
("hwndfrom","intptr",0),
|
|
("idfrom","intptr",0),
|
|
("code","int",0)),
|
|
"guid":(
|
|
("data1","int",0),
|
|
("data2","short",0),
|
|
("data3","short",0),
|
|
("data4","char[8]","")
|
|
)
|
|
);
|
|
//返回值
|
|
r := pcstruct(csstr1,1);
|
|
tslarray := array();
|
|
j := 0;
|
|
if ifarray(r)then tname := r["tname"];
|
|
for i,v in r["field"] do
|
|
begin
|
|
tps := v["t"];
|
|
tp := tps[length(tps)-1];
|
|
if v["p"]then
|
|
begin
|
|
if tp="char" and v["p"]=1 then tp := "char*";
|
|
end
|
|
ctyp := typecp[tp]?: "intptr"; //设置默认类型为指针
|
|
len := v["l"];
|
|
if len then ctyp := ctyp+format("[%s]",len); //设置数组初始值
|
|
tslarray[j++]:= array(v["n"],typetouser(ctyp),typecv[ctyp]?: 0); //构造数据
|
|
end
|
|
return tslarray;
|
|
(*
|
|
csstr := dealcppcomment(csstr1);
|
|
s := pos("{",csstr)+1;
|
|
e := pos("}",csstr);
|
|
//删除注释
|
|
str := copy(lowercase(csstr),s,e-s); //获取大括号之间的数据
|
|
str :=replacestr(str,"\r"," "); //替换掉换行
|
|
str :=replacestr(str,"\n"," "); //替换掉换行
|
|
str :=replacestr(str,"\t"," "); //替换掉分隔符
|
|
strs := str2array(str,";"); //按照;分割行
|
|
//类型对照表
|
|
tslarray := array();
|
|
j := 0;
|
|
//正则表达式表
|
|
//ctrl := "\\w+[*]?";
|
|
for i ,v in strs do
|
|
begin
|
|
parserctypestr(v,tp,len,name);
|
|
if not(name and tp) then continue;
|
|
ctyp := typecp[tp]?:"intptr"; //设置默认类型为指针
|
|
if len then ctyp := ctyp + format("[%d]",len); //设置数组初始值
|
|
tslarray[j++] := array(name,ctyp,typecv[ctyp]?:0); //构造数据
|
|
end
|
|
|
|
|
|
return tslarray; *)
|
|
end
|
|
{
|
|
function writeloglen(len);
|
|
begin
|
|
lf := "d:/ts/malocsize.txt";
|
|
if FileExists("",lf) then
|
|
begin
|
|
pos1 := FileSize('',lf);
|
|
end
|
|
else
|
|
begin
|
|
pos1 := 0;
|
|
end
|
|
a := format("分配空间大小%d",len);
|
|
writefile(rwraw(),'',lf,pos1,length(a),a);
|
|
end }
|
|
function typetouser(tp);
|
|
begin
|
|
if tp in array("nmhdr","guid")then
|
|
begin
|
|
return "user";
|
|
end
|
|
return tp;
|
|
end
|
|
|
|
Initialization
|
|
//Unit Initial statement here
|
|
Finalization
|
|
//Unit Final statement here
|
|
End. |