使用Memcopy进行八位char 跟十六位的short之间的转化

张亚成 2014-04-29 05:39:40
在程序中有时候需要把十六位的short数组转化成八位的char数组,有时候需要把八位的char数组转化成十六位的short数组,看到别的程序上写的是使用memcopy就完成了,
如:
char ch【4】 = {0x01,0x02,0x03,0x04};
short sh[2];
memcopy(sh, ch, 4);
此时 : sh[2] = {0x0102, 0x0304}


但是我总感觉这个使用方法可能会不妥 ?请大家帮忙指点一下。
...全文
368 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
qiminixi 2014-04-30
  • 打赏
  • 举报
回复
引用 11 楼 zhangyacheng_1 的回复:
[quote=引用 10 楼 qiminixi 的回复:] [quote=引用 5 楼 baichi4141 的回复:] [quote=引用 4 楼 qiminixi 的回复:] [quote=引用 1 楼 baichi4141 的回复:] 嗯,有字节序的问题 在另一台机器上结果可能是sh[2] = {0x0201, 0x0403}
得到0x0201, 0x0403是用小头优先得到吧,但是内存中还是0x01020304。这是如何看待数据的问题[/quote] 你算两个int相加的时候不会关心内存中的数据是小头还是大头 数据类型本身就是如何看待数据的标准,如果没有这个需求,何必char转short?既然转了,就代表要用short来做什么[/quote] 如果只认为char转short是为了数0x01与数0x02前后合并后得到数0x0102那我也没什么好说的了。而用这种方法在需要跨平台兼容的情况下也是错误的。[/quote] 最初转化的目的是因为我操作的程序获取到的数据是unsigned char 型的数据,在传送给调用函数的时候调用函数使用的数据类型是unsigned short 类型的 , 调用函数是别人给的dll [/quote] 这样的话,用类转换(unsigned short*)pPtr就可以了。。
张亚成 2014-04-30
  • 打赏
  • 举报
回复
引用 10 楼 qiminixi 的回复:
[quote=引用 5 楼 baichi4141 的回复:] [quote=引用 4 楼 qiminixi 的回复:] [quote=引用 1 楼 baichi4141 的回复:] 嗯,有字节序的问题 在另一台机器上结果可能是sh[2] = {0x0201, 0x0403}
得到0x0201, 0x0403是用小头优先得到吧,但是内存中还是0x01020304。这是如何看待数据的问题[/quote] 你算两个int相加的时候不会关心内存中的数据是小头还是大头 数据类型本身就是如何看待数据的标准,如果没有这个需求,何必char转short?既然转了,就代表要用short来做什么[/quote] 如果只认为char转short是为了数0x01与数0x02前后合并后得到数0x0102那我也没什么好说的了。而用这种方法在需要跨平台兼容的情况下也是错误的。[/quote] 最初转化的目的是因为我操作的程序获取到的数据是unsigned char 型的数据,在传送给调用函数的时候调用函数使用的数据类型是unsigned short 类型的 , 调用函数是别人给的dll
qiminixi 2014-04-30
  • 打赏
  • 举报
回复
引用 5 楼 baichi4141 的回复:
[quote=引用 4 楼 qiminixi 的回复:] [quote=引用 1 楼 baichi4141 的回复:] 嗯,有字节序的问题 在另一台机器上结果可能是sh[2] = {0x0201, 0x0403}
得到0x0201, 0x0403是用小头优先得到吧,但是内存中还是0x01020304。这是如何看待数据的问题[/quote] 你算两个int相加的时候不会关心内存中的数据是小头还是大头 数据类型本身就是如何看待数据的标准,如果没有这个需求,何必char转short?既然转了,就代表要用short来做什么[/quote] 如果只认为char转short是为了数0x01与数0x02前后合并后得到数0x0102那我也没什么好说的了。而用这种方法在需要跨平台兼容的情况下也是错误的。
张亚成 2014-04-30
  • 打赏
  • 举报
回复
还有别的错误可能性吗 ?
张亚成 2014-04-30
  • 打赏
  • 举报
回复
引用 6 楼 baichi4141 的回复:
[quote=引用 2 楼 zhangyacheng_1 的回复:] [quote=引用 1 楼 baichi4141 的回复:] 嗯,有字节序的问题 在另一台机器上结果可能是sh[2] = {0x0201, 0x0403}
此话确定有根据吗, 公司给的参考代码是这个样的写法,发布过的很多程序中就采用的这个方法, 怎么查看机子是使用的什么字节序 ?[/quote] 如果你公司的程序不需要考虑更换运行环境(例如绑定在你公司提供的电脑上不允许在其他电脑上运行),那就随意吧 如果你公司的程序有可能复制到另一台不同硬件的CPU上,那这就是程序BUG,这种程序发布出去就是不负责任 要查看字节序,就用这种方法,设置一个多字节整数为1,用char指针指向它,看第一个字节和最后一个字节哪个是1[/quote] 谢谢你的指点
Lionheartch 2014-04-30
  • 打赏
  • 举报
回复
进来观望学习的
baichi4141 2014-04-30
  • 打赏
  • 举报
回复
引用 2 楼 zhangyacheng_1 的回复:
[quote=引用 1 楼 baichi4141 的回复:] 嗯,有字节序的问题 在另一台机器上结果可能是sh[2] = {0x0201, 0x0403}
此话确定有根据吗, 公司给的参考代码是这个样的写法,发布过的很多程序中就采用的这个方法, 怎么查看机子是使用的什么字节序 ?[/quote] 如果你公司的程序不需要考虑更换运行环境(例如绑定在你公司提供的电脑上不允许在其他电脑上运行),那就随意吧 如果你公司的程序有可能复制到另一台不同硬件的CPU上,那这就是程序BUG,这种程序发布出去就是不负责任 要查看字节序,就用这种方法,设置一个多字节整数为1,用char指针指向它,看第一个字节和最后一个字节哪个是1
baichi4141 2014-04-30
  • 打赏
  • 举报
回复
引用 4 楼 qiminixi 的回复:
[quote=引用 1 楼 baichi4141 的回复:] 嗯,有字节序的问题 在另一台机器上结果可能是sh[2] = {0x0201, 0x0403}
得到0x0201, 0x0403是用小头优先得到吧,但是内存中还是0x01020304。这是如何看待数据的问题[/quote] 你算两个int相加的时候不会关心内存中的数据是小头还是大头 数据类型本身就是如何看待数据的标准,如果没有这个需求,何必char转short?既然转了,就代表要用short来做什么
张亚成 2014-04-30
  • 打赏
  • 举报
回复
引用 14 楼 zhao4zhong1 的回复:
电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……
这个好像不影响这个题目
赵4老师 2014-04-30
  • 打赏
  • 举报
回复
电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……
张亚成 2014-04-30
  • 打赏
  • 举报
回复
回复 : qiminixi 你意思直接使用 short 类型的指针指向char型的数组就行 ? 这样就可以把原来char数组使用两个两个的读给 short 变量么 ? 如果是这个样子,那么就跟 memcopy 是同一个意思。
qiminixi 2014-04-29
  • 打赏
  • 举报
回复
引用 1 楼 baichi4141 的回复:
嗯,有字节序的问题 在另一台机器上结果可能是sh[2] = {0x0201, 0x0403}
得到0x0201, 0x0403是用小头优先得到吧,但是内存中还是0x01020304。这是如何看待数据的问题
张亚成 2014-04-29
  • 打赏
  • 举报
回复
这样做除了字节序可能存在问题之外,还有别的错误可能性吗 ?
张亚成 2014-04-29
  • 打赏
  • 举报
回复
引用 1 楼 baichi4141 的回复:
嗯,有字节序的问题 在另一台机器上结果可能是sh[2] = {0x0201, 0x0403}
此话确定有根据吗, 公司给的参考代码是这个样的写法,发布过的很多程序中就采用的这个方法, 怎么查看机子是使用的什么字节序 ?
baichi4141 2014-04-29
  • 打赏
  • 举报
回复
嗯,有字节序的问题 在另一台机器上结果可能是sh[2] = {0x0201, 0x0403}
没有任何实质性内容更新,仅内部架构调整,更易于派生模块使用; 首发于精易的 易语言全功能 SQLite3 数据库接口模块必须更新到本次版本后方可正常使用!下载:https://bbs.125.la/forum.php?mod=viewthread&tid=14361253 wow64 是在 64 位操作系统上允许 32 位程序(比如易编译的程序)执行的模拟器子系统;在 64 位操作系统中,不管你的程序是 32 还是 64 位的,其实都存在两个地址空间,正常情况下 32 位程序访问的自然是 32 位的地址空间,而 64 位程序访问其 64 位地址空间。 但是这两个空间是同时存在且可以切换的,本模块就是通过该原理切换到 64 位地址空间获取 ntdll.dll 相关函数进行调用(注:此基址是 64 位的,与平常获取的 32 位模块基址截然不同); 也就是:wow 环境 -> 进入 x64 环境 -> x64 函数调用 或 x64 汇编代码 -> 退出 x64 环境 -> wow 环境,以上必须在一个子程序内完成; 部分实现代码借鉴 c++ 开源代码:wow64ext,在此感谢作者 rewolf。 实现易语言纯 64 位汇编置入代码; 允许调用易程序 64 位 ntdll.dll 的所有函数,也就是你虽然开发的是 32 位程序,但可以实现很多 64 位函数所能实现的功能; 直接使用 64 位函数自由读写(注入) 64 位进程,与很多模块调用 NtWow64xxx 系列函数实现的方式有本质不同; 部分常用 ntdll.dll 函数已在模块直接提供,或以模拟 kernel32 函数的调用形式提供,v1.1 新增多个函数; 未提供函数获取地址后,可使用 X64Call 这个通用函数调用即可; 大部分提供的 64 位功能也同时提供了 32 位版本,以便兼容不同需求(模块在 32 位系统中不会开启 64 位功能引起异常,但 32 位功能依然可用); 支持加载任意 32/64 位 DLL,从此易语言可以调用外部 64 位 DLL 了(包括加载 kernel32.dll),v1.1 新增功能; 除了动态加载外,还支持 32 位 DLL 的内存加载,但 64 位只能加载本地 DLL 文件,v1.1 新增功能; 如有 BUG,请提供错误重现代码及执行环境,如非不可抗因素我都会及时更新的; 以下只是适用于 64 位的部分函数,模块中以相同命令形式实现的 32 位命令,这里就不列举了; 辅Zhu函数 fn_WOW64Enabled 如果你在代码中需要使用 64 位汇编或者操作 64 位进程,则初始化时应确保本函数返回真。实际只要是 64 位操作系统,均应返回 真 fn_ProcessIsX64 检测指定进程是否为 64 位进程 fn_CalcModOrFuncHash 使用过动态调用DLL的都清楚取模块基址和函数指针,微软默认使用字符串对比,本模块可使用哈希对比效率和易用上相对提升,本函数用于计算模块或函数哈希 X64Call 调用 64 位函数通用版本 X64CallArr 调用 64 位函数通用版本,数组方式传参,支持无限个数参数;【v1.2新增】 X64MemCopy 同类还有 X64MemCmp 函数;从 64 地址复制数据或 64 位地址与 32 位地址数据对比,但仅限进程内部 X64GetLong64 获取 64 位地址数值,同类函数还有:X64GetLong32、X64GetWord、X64GetByte X64GetTEB 取当前易程序 64 位 TEB,通过 TEB 再取 PEB,则进程和线程信息以及模块等一览无余了 GetNtdll64 ntdll.dll 在 64 位环境下的内存基址 GetModuleHandleEx64 通过模块哈希值获取其 64 位地址空间的内存基址(易进程而不是外部进程哦);同类还有 GetModuleHandle64 GetProcAddressEx64 通过函数哈希值或函数索引序号获取其 64 位调用地址;同类还有 GetProcAddress64 NtQuerySystemInformation64 cha询系统信息,可获取很多类别信息。这个 API 微软已不推荐使用并给出部分替代 API,但其个别功能十分好用且没用可替代品。cha询系统进程也是最全面的 OpenProcess64 打开进程句柄,关闭进程句柄时使用 CloseHandle64;【v1.1新增】 HeapAlloc64 堆管理函数,同类还有 GetDefaultHeap64/HeapReAlloc64/HeapFree64/HeapSize64;【v1.1新增】 malloc64 简化版默认堆管理函数,同类还有 realloc64/fre
模块原理: wow64 是在 64 位操作系统上允许 32 位程序(比如易编译的程序)执行的模拟器子系统;在 64 位操作系统中,不管你的程序是 32 还是 64 位的,其实都存在两个地址空间,正常情况下 32 位程序访问的自然是 32 位的地址空间,而 64 位程序访问其 64 位地址空间。 但是这两个空间是同时存在且可以切换的,本模块就是通过该原理切换到 64 位地址空间获取 ntdll.dll 相关函数进行调用(注:此基址是 64 位的,与平常获取的 32 位模块基址截然不同); 也就是:wow 环境 -> 进入 x64 环境 -> x64 函数调用 或 x64 汇编代码 -> 退出 x64 环境 -> wow 环境,以上必须在一个子程序内完成; 部分实现代码借鉴 c++ 开源代码:wow64ext,在此感谢作者 rewolf。 模块功能: 实现易语言纯 64 位汇编置入代码; 允许调用易程序 64 位 ntdll.dll 的所有函数,也就是你虽然开发的是 32 位程序,但可以实现很多 64 位函数所能实现的功能; 直接使用 64 位函数ziyou读写(注入) 64 位进程,与很多模块调用 NtWow64xxx 系列函数实现的方式有本质不同; 部分常用 ntdll.dll 函数已在模块直接提供,或以模拟 kernel32 函数的调用形式提供,v1.1 新增多个函数; 未提供函数获取地址后,可使用 X64Call 这个通用函数调用即可; 大部分提供的 64 位功能也同时提供了 32 位版本,以便兼容不同需求(模块在 32 位系统中不会开启 64 位功能引起异常,但 32 位功能依然可用); 支持加载任意 32/64 位 DLL,从此易语言可以调用外部 64 位 DLL 了(包括加载 kernel32.dll),v1.1 新增功能; 除了动态加载外,还支持 32 位 DLL 的内存加载,但 64 位只能加载本地 DLL 文件,v1.1 新增功能; 如有 BUG,请提供错误重现代码及执行环境,如非不可抗因素我都会及时更新的; 部分命令简述: 以下只是适用于 64 位的部分函数,模块中以相同命令形式实现的 32 位命令,这里就不列举了; 辅助函数 fn_WOW64Enabled 如果你在代码中需要使用 64 位汇编或者操作 64 位进程,则初始化时应确保本函数返回真。实际只要是 64 位操作系统,均应返回 真 fn_ProcessIsX64 检测指定进程是否为 64 位进程 fn_CalcModOrFuncHash 使用过动态调用DLL的都清楚取模块基址和函数指针,微软默认使用字符串对比,本模块可使用哈希对比效率和易用上相对提升,本函数用于计算模块或函数哈希 易内部命令 X64Call 调用 64 位函数通用版本 X64MemCopy 同类还有 X64MemCmp 函数;从 64 地址复制数据或 64 位地址与 32 位地址数据对比,但仅限进程内部 X64GetLong64 获取 64 位地址数值,同类函数还有:X64GetLong32、X64GetWord、X64GetByte X64GetTEB 取当前易程序 64 位 TEB,通过 TEB 再取 PEB,则进程和线程信息以及模块等一览无余了 GetNtdll64 ntdll.dll 在 64 位环境下的内存基址 GetModuleHandleEx64 通过模块哈希值获取其 64 位地址空间的内存基址(易进程而不是外部进程哦);同类还有 GetModuleHandle64 GetProcAddressEx64 通过函数哈希值或函数索引序号获取其 64 位调用地址;同类还有 GetProcAddress64 NtQuerySystemInformation64 查询系统信息,可获取很多类别信息。这个 API 微软已不推荐使用并给出部分替代 API,但其个别功能十分好用且没用可替代品。查询系统进程也是最全面的 OpenProcess64 打开进程句柄,关闭进程句柄时使用 CloseHandle64;【v1.1新增】 HeapAlloc64 堆管理函数,同类还有 GetDefaultHeap64/HeapReAlloc64/HeapFree64/HeapSize64;【v1.1新增】 malloc64 简化版默认堆管理函数,同类还有 realloc64/free64 RtlUnicodeToAnsi64 内核实现的 Unicode、Ansi 结构(不是数据指针)管理函数,同类还有:RtlInitAnsiString64/RtlFreeAnsiString64、RtlInitUnicodeString64/RtlFreeUnicodeString64、RtlAnsiToUnicode

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧