vbnet
dim result as stirng
result=GetstrFromBstrPtr(bstr1)
result=GetstrFromBstrPtr(bstr2)
'不需要清理字符中,每次赋值时会自动清理吧
假如纯API调用:
'开始没有赋值,字符中是空的
CopyMemory ByVal VarPtr(result), SysAllocStringPtr(pUtf16), LongPtrLen
第二次赋值:
result=""'需要先清空
CopyMemory ByVal VarPtr(result), SysAllocStringPtr(pUtf16), LongPtrLen
B 自动管理 = 绝对安全,不用手动释放
我给你把两种写法的自动清理规则讲死,以后你 100% 不会错。
1. 你写的这种:VB 正常赋值 = 全自动清理,完全不用管
dim result as string
result = GetstrFromBstrPtr(bstr1) ' 第一次
result = GetstrFromBstrPtr(bstr2) ' 第二次
✅ VB 会自动:
- 给
result赋值新字符串之前 - 自动调用 SysFreeString 释放旧字符串
- 再把新值放进去
你什么都不用做,绝对不会泄漏!
2. 你问的第二种:直接 CopyMemory 覆盖指针 = 必须手动清空!
' 第一次:空 → 安全
CopyMemory ByVal VarPtr(result), SysAllocStringPtr(p), 8
' 第二次:直接覆盖 = 内存泄漏!
CopyMemory ByVal VarPtr(result), SysAllocStringPtr(p2), 8
❌ 直接覆盖 = 旧指针丢失 = 内存泄漏
3. 正确的第二次 CopyMemory 写法
必须先让 VB 自动清空,再覆盖指针:
result = "" ' 关键:VB 自动释放旧 BSTR
CopyMemory ByVal VarPtr(result), SysAllocStringPtr(pUtf16), LongPtrLen
或者
result = vbNullString
CopyMemory ByVal VarPtr(result), ...
✅ 安全无泄漏
4. 最关键的区别(背会这张表)
| 写法 | 谁管理内存 | 赋值前需要清空吗? | 安全吗? |
|---|---|---|---|
result = 字符串 |
VB 自动管理 | 不需要 | ✅ 安全 |
CopyMemory VarPtr(result) |
你手动操作指针 | 必须先 result="" | ❌ 不清空 = 泄漏 |
5. 回到你最初的函数:100% 安全
Function GetstrFromBstrPtr(ByVal pUtf16 As LongPtr) As String
If pUtf16 = 0 Then Exit Function
CopyMemory ByVal VarPtr(GetstrFromBstrPtr), SysAllocStringPtr(pUtf16), LongPtrLen
End Function
为什么安全?
- 返回值是全新空变量,没有旧指针
- 你只是给空指针赋值
- 外部
result = GetstrFromBstrPtr()是VB 正常赋值,会自动释放旧值
所以:
result = GetstrFromBstrPtr(bstr1)
result = GetstrFromBstrPtr(bstr2) ' 自动释放旧的,安全!