易语言 指针还原自定义数据方法
姿势New
2022年06月17日 19:53

在易语言中数组通过指针传递与还原的方法分享一下个人的研究学习心得 方法一、纯文本型自定义数据结构(这个结构中成员全部类型全部是文本型的) 数据结构: ————————————————————————————————————– .版本 2

.数据类型 _自定数据, , 9个成员 9*4=36 .成员 name, 文本型 .成员 pass, 文本型 .成员 zhpass, 文本型 .成员 cs, 文本型 .成员 buyadd, 文本型 .成员 copyright, 文本型 .成员 gginfo, 文本型 .成员 title, 文本型 .成员 ggtype, 文本型 ————————————————————————————————————– 还原写法: ————————————————————————————————————– .版本 2 .支持库 spec

.子程序 纯文本型_自定义数据_转数组, , 公开, 处理自定义数据 类型全部为文本型 .参数 数据地址, , , 取变量数据地址()得到 .参数 原自定义数据成员数 .参数 返回文本数组, 文本型, 参考 可空 数组 .局部变量 i, 整数型 .局部变量 首成员地址

.如果真 (数据地址 = 0) 返回 () .如果真结束 首成员地址 = 指针到整数 (数据地址) 调试输出 (指针到整数 (数据地址)) 加入成员 (返回文本数组, 指针到文本 (指针到整数 (首成员地址))) .变量循环首 (4, 原自定义数据成员数 × 4 - 4, 4, i) 加入成员 (返回文本数组, 指针到文本 (指针到整数 (首成员地址 + i))) .变量循环尾 () 调试输出 (返回文本数组) ————————————————————————————————————–

方法二,使用写到内存及API LocalSize() RtlMoveMemory()’拷贝内存 RtlZeroMemory()’内存清零 DLL代码: ————————————————————————————————————– .版本 2

.DLL命令 LocalSize, 整数型, “kernel32”, “LocalSize”, , 取数据内存中长度 .参数 hMem, 整数型, , 指针到整数 (取变量数据地址()) 一定能得到数据长度 然后就可以使用 写到内存 愉快的还原了

.DLL命令 拷贝内存_, 整数型, “kernel32”, “RtlMoveMemory”, , RtlMoveMemory .参数 目标数据地址, 整数型, , lpvDest .参数 源数据, 整数型, , lpvSource .参数 尺寸, 整数型, , cbCopy

.DLL命令 内存清零_, , “kernel32.dll”, “RtlZeroMemory”, , ZeroMemory .参数 目的内存, 整数型, , Destination .参数 长度, 整数型, , Length

————————————————————————————————————– 数据结构: ————————————————————————————————————– .版本 2

.数据类型 数据类型1 .成员 a, 长整数型 .成员 b, 整数型 .成员 c, 文本型 ————————————————————————————————————– .版本 2 .支持库 spec

.子程序 子程序1, 整数型

a.a = 求次方 (2, 62) a.b = 取启动时间 () a.c = 到文本 (取启动时间 ()) 加入成员 (c, a) 返回 (取变量数据地址 (a)) ‘ a是个程序集自定义数据变量

————————————————————————————————————– 有问题的还原写法,此方法会造成只能读取一次: ————————————————————————————————————– .版本 2 .支持库 spec

.子程序 _按钮1_被单击, , , 还原写法 .局部变量 a, 数据类型1 .局部变量 数据地址 .局部变量 内存写入长度

数据地址 = 子程序1 () 内存写入长度 = LocalSize (指针到整数 (数据地址)) 写到内存 (指针到整数 (数据地址), 取变量数据地址 (a), 内存写入长度) 调试输出 (a.a, a.b, a.c) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 正确的写法: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .版本 2 .支持库 spec

.子程序 _按钮1_被单击, , , 还原写法 .局部变量 a, 数据类型1 .局部变量 数据地址 .局部变量 内存写入长度

数据地址 = 子程序1 () 内存写入长度 = LocalSize (指针到整数 (数据地址)) 拷贝内存_ (指针到整数 (取变量数据地址 (a)), 指针到整数 (数据地址), 内存写入长度) 调试输出 (a.a, a.b, a.c) ‘调用完成后一定要释放掉这个内存不然下次可能会出错 内存清零_ (指针到整数 (取变量数据地址 (a)), 内存写入长度) ————————————————————————————————————– 数组的还原方法错误的写法,此方法会造成关闭时报错 : ————————————————————————————————————– .版本 2 .支持库 spec

.子程序 _按钮2_被单击 .局部变量 数据地址 .局部变量 数组数量 .局部变量 a, 数据类型1, , “0” .局部变量 b, 长整数型, , , 无用 仅仅用于查看验证我的个人想法 .局部变量 i, 整数型

数据地址 = 子程序2 () ‘ 得到数组变量数据地址 调试输出 (“数据地址”, 数据地址) 数组数量 = 指针到整数 (数据地址 - 4) ‘ 按固定格式-4得到 数组成员数 调试输出 (“数组数量”, 数组数量) 重定义数组 (a, 假, 数组数量) ‘ 这一步必不可少 如果少了 就一定会报错,我个人理解应该是相当于申请了内存地址 调试输出 (a, “查看重定义后数组”) ‘ 调试输出 (指针到整数 (数据地址), “这里就是数组的第一个成员指针地址”) ‘ b = 取字节集数据 (指针到字节集 (指针到整数 (数据地址), 8), #长整数型, ) ‘ 调试输出 (b, “这里已经还原首指针数据”)

调试输出 (LocalSize (指针到整数 (数据地址)), , “查看原数据结构长度”) 写到内存 (指针到整数 (数据地址), 取变量数据地址 (a), LocalSize (指针到整数 (数据地址))) ‘ 还原自定义数据数组 ‘ 把外壳指针还原为真实的指针, 得到需要还原数组地址 长度通过API计算的好处是可以还原所有数组 .计次循环首 (取数组成员数 (a), i) ‘ 到这一步已经还原了数组 调试输出 (a [i].a, a [i].b, a [i].c) .计次循环尾 () ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 正确的数组还原写法: ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .版本 2 .支持库 spec

.子程序 _按钮5_被单击, , , 真正的正确的自定义数组还原算法 .局部变量 变量数据地址_ .局部变量 变量数据地址_成员 .局部变量 变量数据地址_结构长度 .局部变量 变量地址_ .局部变量 变量地址_成员 .局部变量 变量地址_结构长度 .局部变量 变量地址_数组, 数据类型1, , “0” .局部变量 i, 整数型 .局部变量 变量数据地址_数组, 数据类型1, , “0”

变量数据地址_ = 取变量数据地址 (zd) 变量数据地址_成员 = 指针到整数 (变量数据地址_ - 4) 变量数据地址_结构长度 = 取数据内存占用长度_ (变量数据地址_ - 8)

‘ 调试输出 (变量数据地址_, 变量数据地址_成员, 变量数据地址_结构长度, 取十六进制文本 (变量数据地址_), 取十六进制文本 (指针到整数 (变量数据地址_))) ‘ =========================== 变量地址_ = 取变量地址 (zd) 变量地址_成员 = 指针到整数 (指针到整数 (变量地址_) + 4) 变量地址_结构长度 = 取数据内存占用长度_ (指针到整数 (变量地址_)) 调试输出 (变量数据地址_ - 8, 指针到整数 (变量地址_)) 调试输出 (变量数据地址_, 变量数据地址_成员, 变量数据地址_结构长度, 取十六进制文本 (变量数据地址_), 取十六进制文本 (指针到整数 (变量数据地址_))) 调试输出 (变量地址_, 变量地址_成员, 变量地址_结构长度, 取十六进制文本 (变量地址_), 取十六进制文本 (指针到整数 (变量地址_))) ‘ 由此得出, 调试输出 (取变量数据地址 (zd), 指针到整数 (取变量地址 (zd)) + 8) ‘ 把取到变量地址 转为 指针+8 就等于 取变量地址 调试输出 (取变量数据地址 (zd) - 8, 指针到整数 (取变量地址 (zd))) ‘ ===由变量地址 得到完整的数组 ‘ 这玩意轻松得到数组 重定义数组 (变量地址_数组, 假, 变量地址_成员) 拷贝内存_ (指针到整数 (取变量地址 (变量地址_数组)), 指针到整数 (变量地址_), 变量地址_结构长度) .计次循环首 (变量地址_成员, i) 调试输出 (变量地址_数组 [i].srt, 变量地址_数组 [i].int, , “取变量地址”) .计次循环尾 () 内存清零_ (指针到整数 (取变量地址 (变量地址_数组)), 变量地址_结构长度) ‘ ====取变量数据地址 重定义数组 (变量数据地址_数组, 假, 变量数据地址_成员) 拷贝内存_ (取变量数据地址 (变量数据地址_数组) - 8, 变量数据地址_ - 8, 变量数据地址_结构长度) .计次循环首 (变量数据地址_成员, i) 调试输出 (变量数据地址_数组 [i].srt, 变量数据地址_数组 [i].int, “变量数据地址”) .计次循环尾 () 内存清零_ (取变量数据地址 (变量数据地址_数组) - 8, 变量数据地址_结构长度)

————————————————————————————————————–

注意:这里的数组,或自定义数据 必须是程序集或全局变量才行,否则一定会报错。如果非要用局部变量 记得勾选 静态 否则子程序执行完毕 后这个变量就释放掉了 你是得不到任何东西的!