用VarPtr传给CopyMemory拷贝字符串 为啥结果不正确

slowgrace 2009-09-01 09:52:22
加精
Option Explicit

Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(pDest As Any, pSource As Any, ByVal byteLen As Long)

Sub test2()
Dim String1 As String
Dim String2 As String
Dim pString1 As Long

String1 = "PowerVB"
String2 = String$(7, 0)

'Try three: Get the string's pointer from VarPtr
CopyMemory pString1, ByVal VarPtr(String1), 4
CopyMemory ByVal String2, ByVal pString1, 14

Debug.Print String2 '得到的不是PowerVB,而是“P o w e”?为什么?
End Sub


slowgrace
2 分钟前

以下为本帖小结 ==================================================
谢谢许多朋友热心回复,尤其是赵老虎的全程指点和陈辉版主的推荐!我觉得这个帖子信息量挺大的,想了解VB6对API函数的字符串参数处理机制的同学可以仔细看一看。后来的朋友推荐按以下顺序看:
基础知识:196楼+197楼;187楼+222楼;184楼+189楼;30+31楼;88楼+119楼+这个帖子的17楼+25楼;35+36+39楼;74楼+78楼;118楼;160楼;191楼+192楼
例1:194楼+198楼;
例2:0楼+90楼+210楼
例3:229楼
例4:16楼+162楼+132楼+184楼+246楼
例5:10楼+248楼+252楼
例6:34楼+40楼+92楼+125楼
例7:129楼+130+134+141+143+269+276


或者看我在博客里写的小结:()、()、()、()。
...全文
4355 293 打赏 收藏 转发到动态 举报
写回复
用AI写文章
293 条回复
切换为时间正序
请发表友善的回复…
发表回复
supertankhzt 2012-05-06
  • 打赏
  • 举报
回复
好贴啊!研究了二天,受益匪浅。
ldfaltxj 2010-09-16
  • 打赏
  • 举报
回复
学习了,不错
特别 2009-11-23
  • 打赏
  • 举报
回复
楼主这个小结做的挺厚道的
slowgrace 2009-10-23
  • 打赏
  • 举报
回复
复习一遍,结帖了。

谢谢各位朋友热心回复。

为了方便后来的朋友,我这样给分的:
(1)比较重要的结论性的东西给分较高;
(2)给出代码的都给了2分,注意这些代码有不少是错误的,但是通过分析这些代码的错误可以用来帮助熟悉巩固所学到的知识(见273楼)。
slowgrace 2009-09-16
  • 打赏
  • 举报
回复
灰常感谢。我先试试,如果有问题,另外开帖请教。
Tiger_Zhao 2009-09-16
  • 打赏
  • 举报
回复
无论大小,反正代码块数不多,推荐用 TextPad
1)首先当然是设好 VB 的语法高亮。
2)如果你嫌新建文档通过属性选语法麻烦,可以用一个空白的 .bas 文件作为粘贴的文档
3)粘贴代码
4)★全选,然后在编辑菜单中选“其他复制\作为 HTML 页面”
5)不需要完整的 HTML 页面内容,粘贴到一个新的文档中
6)如果 Blog 不支持自定义样式,你就将里面的 <span class="..."> 替换为 <font color="..">,这可以录个宏,以后执行一下就可以了。
7)将内容部分的 HTML 段落复制出来就能用了。
slowgrace 2009-09-16
  • 打赏
  • 举报
回复
你眼真尖
slowgrace 2009-09-16
  • 打赏
  • 举报
回复
大段的代码着色我用的是CSDN博客编辑器带的语法高亮工具
小段的代码着色我用的是Live Writer的语法高亮插件

这两个工具都不能语法高亮Debug.Print
小写的 as long 没有着色,这个是CSDN工具的显示结果。
Tiger_Zhao 2009-09-16
  • 打赏
  • 举报
回复
[Quote=引用 278 楼 slowgrace 的回复:]或者看我在博客里写的小结:(一)、(二)、(三)、(四)。[/Quote]
你用什么代码着色工具,Debug.Print 没有着色,小写的 as long 也没有着色,难道是 Pretty Code?
slowgrace 2009-09-16
  • 打赏
  • 举报
回复
谢谢楼上各位夸奖!谢谢豆子版主及其他各位版主帮助置顶小结!
zzyong00 2009-09-15
  • 打赏
  • 举报
回复
非常精彩的论文!!赞一下!
嗷嗷叫的老马 2009-09-15
  • 打赏
  • 举报
回复
[Quote=引用 279 楼 chenhui530 的回复:]
刚才我去你博客看了下,西西够强,是我是没那么多心事去编辑排版之类的
这样做方便后来学习的爱好者,我的博客为了偷懒几乎全是贴代码
[/Quote]
你的文章一读就要出人命------------------从不写标点的家伙
嗷嗷叫的老马 2009-09-15
  • 打赏
  • 举报
回复
[Quote=引用 279 楼 chenhui530 的回复:]
刚才我去你博客看了下,西西够强,是我是没那么多心事去编辑排版之类的
这样做方便后来学习的爱好者,我的博客为了偷懒几乎全是贴代码
[/Quote]
你的文章一读就要出人命------------------从不写标点的家伙
chenhui530 2009-09-15
  • 打赏
  • 举报
回复
刚才我去你博客看了下,西西够强,是我是没那么多心事去编辑排版之类的
这样做方便后来学习的爱好者,我的博客为了偷懒几乎全是贴代码
slowgrace 2009-09-15
  • 打赏
  • 举报
回复
或者看我在博客里写的小结:()、()、()、()。
slowgrace 2009-09-15
  • 打赏
  • 举报
回复
以下为本帖小结
==================================================
谢谢许多朋友热心回复,尤其是赵老虎的全程指点!我觉得这个帖子信息量挺大的,想了解VB6对API函数的字符串参数处理机制的同学可以仔细看一看。后来的朋友推荐按以下顺序看:

基础知识:196楼+197楼;187楼+222楼;184楼+189楼;30+31楼;88楼+119楼+这个帖子的17楼+25楼;35+36+39楼;74楼+78楼;118楼;160楼;191楼+192楼
例1:194楼+198楼;
例2:0楼+90楼+210楼
例3:229楼
例4:16楼+162楼+132楼+184楼+246楼
例5:10楼+248楼+252楼、
例6:34楼+40楼+92楼+125楼
例7:129楼+130+134+141+143+269+276

或者看我在博客里写的小结:(<a href="http://blog.csdn.net/slowgrace/archive/2009/09/14/4549926.aspx" target="_blank">一</a>)、(<a href="http://blog.csdn.net/slowgrace/archive/2009/09/14/4550116.aspx">二</a>)、(<a href="http://blog.csdn.net/slowgrace/archive/2009/09/14/4550293.aspx" target="_blank">三</a>)、(<a href="http://blog.csdn.net/slowgrace/archive/2009/09/14/4550530.aspx" target="_blank">四</a>)。
Tiger_Zhao 2009-09-14
  • 打赏
  • 举报
回复
[Quote=引用 269 楼 slowgrace 的回复:]那这么说,像我下面这样的用法都是错误的?都会导致重复释放Stirng1的内存和String2原来的内存泄露?[/Quote]
(1)适用于声明的函数中参数为 As String 时,不能在 As Any 时使用。
(2)和(3):String1 原先的字符串指针丢失而导致内存泄漏,而 String1 和 String2 同时引用一个字符串会导致重复释放、可能引发崩溃。
嗷嗷叫的老马 2009-09-13
  • 打赏
  • 举报
回复
帮你断...............
slowgrace 2009-09-13
  • 打赏
  • 举报
回复
出错的方式主要有两种:一种出错的方式是直接拷贝字符串缓冲区指针;还一种出错的方式是无意中把字符串指针当做缓冲区指针用。

这两种方式的错都很隐蔽,因为都能得到正确的结果,但是后果可能很严重。
slowgrace 2009-09-13
  • 打赏
  • 举报
回复
除了上面详细讨论过的,还有许多朋友给出了自己的修正代码,感谢各位。综述如下:

8楼-蚜虫,正确。
这个实际是对0楼代码的直接修正。先扩充String2的长度以确保对应的_tmp2长度足够;最后再做UA转换以抵消VB多做的一次AU转换。

9楼-阿勇,正确。
不经过UA/AU转换,直接拷贝字符串缓冲区。

12楼-lor12,正确。
不经过UA/AU转换,直接拷贝字符串缓冲区。

15楼-赵老虎(1),正确。
目的和源同时做UA/AU转换,直接拷贝字符串缓冲区。

15楼-赵老虎(2),正确。
不经过UA/AU转换,直接拷贝字符串缓冲区。

22楼-珠珠,错误。
同10楼。见248楼解释。

23楼-Veron,错误。
同10楼。见248楼解释。

38楼-坏上帝,正确。
直接传递字符串参数要得到正确结果,很重要的一点是要算对字节数。坏上帝专门写了个函数来算ASCI字符串所占的字节数,所以能够得到正确的结果。不过的话,我觉得这个GetStringLength函数完全可以简化为这一条语句:LenB(StrConv("我有点slow", vbFromUnicode))

46楼-陈辉,正确。
同15楼第一种方法。

50楼-陈辉(1),正确。
同8楼。

50楼-陈辉(2),正确。
同15楼第一种方法。(但解释不完全准确:)

57楼-陈辉,正确。
这个其实同15楼第一种方法,但是更通用。在直接传字符串参数的时候,要用ANSI字符串来计算字节。

58楼-陈辉,不完全正确。
String2的初始化长度取为Len(String1)就可以了。

62楼-陈辉,正确。
用ByVal VarPtr(ByVal String1),呵呵,真够绕的。

129楼-陈辉,错误。
拷贝字符串缓冲区指针会导致重复释放内存。见134,141楼解释。

165楼-(stt505249046),正确。同9楼。
但使用了Len和LenB函数,使得代码更通用了。

231楼-老张,错误。
拷贝字符串缓冲区指针会导致重复释放内存和内存泄露。见134,141楼解释。

237楼-阿勇,错误。
拷贝字符串缓冲区指针会导致重复释放内存和内存泄露。见134,141楼解释。
加载更多回复(269)
学习并掌握C++2.0(11+14+17+20)的新特性,学习线程及线程池的应用 ---------------------------------------------------给小白学员的3年学习路径及计划技术方面分三块:1.纯开发技术方向2.音视频流媒体专业方向3.项目实战---------------------------------------------------1.纯开发技术方向(1) C++必须要过硬(至少学会10本经典好书)(2) 系统级编程(Windows、Linux),必须特别熟练系统API,灵活运用(3) 框架与工具(Qt、MFC):必须精通其中一种。(4) 架构与设计模式:需要提升一个高度,不再是简单的编码,而是思维模式。(5) 驱动级别(如果有兴趣,可以深入到驱动级:包括Windows、Linux)(6) 最好学习点Java+Html+javascript等WEB技术。2.音视频流媒体专业方向(1) 音视频流媒体基础理论:   必须认真学会,否则看代码就是看天书(2) 编解码方向:精通h.264,h.265(hevc), 包括理论和各个开源库(ffmpeg,libx264,libx265,...)。(3) 直播方向:  精通各种直播协议(rtsp,rtmp,hls,http-flv,...), 钻研各个开源库(live555,darwin,srs,zlmediakit,crtmpserver,...)(4) 视频监控:  理论+开源库(onvif+281818)(EasyMonitor、iSpy、ZoneMinder(web)、...) 3.项目实战(1) Qt项目:  至少要亲手练习10个实战项目(网络服务器、多线程、数据库、图像处理、多人聊天、等等)(2)音视频项目:包括编解码、视频监控、直播等各个方向,都需要亲手实战项目,包括视频服务器、后台管理系统、前端播放器(多端)---------------------------------------------------  第1章 C++11新特性 41). nullptr关键字与新语法 42). auto和decltype类型推导 6 auto讲解 6 auto示例 7 decltype 83). for区间迭代 94). 初始化列表 105). 模板增强 11外部模板 11类型别名模板 12默认模板参数 126). 构造函数 13委托构造 13继承构造 147). Lambda 表达式 158). 新增容器 20std::array 20std::forward_list 21无序容器 22元组 std::tuple 239). 正则表达式 2610). 语言级线程支持 28多线程库简介 2811). 右值引用和move语义 31右值引用和move语义 32转移左值 3412). constexpr 35第2章 C++14新特性 36Lambda 函数 36类型推导 37返回值类型推导(Return type deduction) 37泛型lambda 39[[弃用的]]  [[deprecated]]属性 40二进制数字和数字分隔符 41第3章 C++17新特性 42安装GCC10.2 42安装msys2-x86_64-20200720 42更新镜像 42更新软件库 43安装 MinGW64 等必要的软件 43环境变量Path 43编译命令 43constexpr 44typename 45折叠表达式 47结构化绑定 48条件分支语句初始化 49聚合初始化 50嵌套命名空间 52lambda表达式捕获*this的值 53改写/继承构造函数 54用auto作为非类型模板参数 55__has_include 56fallthrough 57nodiscard 57maybe_unused 58第4章 C++20新特性 59编译命令 59concept 59typename 60explicit 61constinit 62位域变量的默认成员初始化 62指定初始化 63基于范围的for循环初始化 64放宽基于范围的for循环,新增自定义范围方法 65嵌套内联命名空间 66允许用圆括弧的值进行聚合初始化 67unicode字符串字面量 68允许转换成未知边界的数组 68likely和unlikely 69第5章 C++2.0(11/14/17/20)总结与分析 705.1 C语言与C++ 715.2 语言可用性的强化 725.2.1 常量 725.2.2 变量及其初始化 735.2.3 类型推导 745.2.4 控制流 765.2.5 模板 775.2.6 面向对象 815.3 语言运行期的强化 835.3.1 Lambda 表达式 835.3.2 右值引用 865.4 容器 885.4.1 线性容器 885.4.2 无序容器 895.4.3 元组 895.5 智能指针与内存管理 905.5.1 RAII 与引用计数 905.5.2 std::shared_ptr 905.5.3 std::unique_ptr 915.5.4 std::weak_ptr 91第6章 C++2.0多线程原理与实战 93什么是并发 93并发的方式 93为什么使用并发 95线程简介 96创建线程的三种方式 971. 通过函数 972.通过类对象创建线程 993.通过lambda表达式创建线程 101thread线程的使用 101互斥量与临界区 105期物Future 111条件变量 112原子操作 114内存模型 118第7章 C++2.0线程池原理与实战 120线程与线程池的基本原理 1201)、线程 1202)、线程的生命周期 1213)、什么是单线程和多线程 1214)、线程池 1225)、四种常见的线程池 123线程池的架构与流程 123线程池代码实战 125    

7,762

社区成员

发帖
与我相关
我的任务
社区描述
VB 基础类
社区管理员
  • VB基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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