使用宏简化您的 Safearray 循环






3.67/5 (3投票s)
2001 年 7 月 31 日
3分钟阅读

132873

1614
一篇关于如何简化 safearray 使用的文章
本文的目的是展示如何在 VC++ 中简化你的 safearray 编程,以及如何使代码更具可读性。本文将简要定义 safearray,并介绍一组新的宏以及如何使用它们。
Safearrays
什么是 Safearrays?正如其名称所示,它是一种安全的数组数据类型,这意味着它会跟踪其限制和边界,因此限制在这些边界内的访问。Safearrays 用于传递封装在 Variants 中的数组(它们的基类型是 VT_?
| VT_ARRAY
),例如在 COM 对象之间。
Safearrays 绝对不能与 C/C++ 数组混淆,C/C++ 数组不 "安全"。在使用 Visual Basic COM 对象和 Visual Basic 数组时,你唯一的选择是学习如何使用 Safearrays,MSDN 是一个关于此主题的良好信息来源(或者可能是未来更详尽的文章 :-)。
如何循环遍历 Safearray
那些熟悉 Safearrays 的人知道,遍历 Safearray 需要大量的代码行。下面的示例 [示例 1] 显示了在遍历包含 Variants 的 Safearray 时代码的样子。
// Safearray loop [sample 1] // this example assumes that you have a Safearray in a VARIANT (vArray) // with the type VT_ARRAY | VT_BSTR // variables LONG lstart, lend; LONG idx = -1; LONG nPos; HRESULT hr; BSTR* pbstr; // assign the Safearray SAFEARRAY *sa = V_ARRAY( &vArray ); // Get the lower and upper bound hr = SafeArrayGetLBound( sa, 1, &lstart ); if(FAILED(hr)) return hr; hr = SafeArrayGetUBound( sa, 1, &lend ); if(FAILED(hr)) return hr; // loop hr = SafeArrayAccessData(sa,(void HUGEP**)&pbstr); if(SUCCEEDED(hr)) { for(idx=lstart; idx <= lend; idx++) { CComBSTR s; s = pbstr[idx]; // s now contains the item at position idx in the array // ... } hr = SafeArrayUnaccessData(sa); if(FAILED(hr)) return hr; } else return hr // (23 lines of code)
注意代码量,想象一下,如果我们能将其减少到 8 行,并想想你的代码将更容易解释,也更容易让其他人理解。
提示! 还要注意我们如何使用 SafeArrayAccessData
来访问循环中的数据,而不是使用 SafeArrayGetElement
来提高性能。
如何使用宏循环 Safearray
为了使我的代码更容易阅读并使编程更快,我创建了一组宏来使 Safearray 编程更容易。让我们看看上面相同的示例 [示例 1],使用宏 [示例 2]。
// Safearray loop [sample 2] // this example assumes that you have a Safearray in a VARIANT (vArray) with // the type VT_ARRAY | VT_BSTR #include "safearray_macro.h" // variables BSTR* pbstr; // loop BEGIN_SA_V(vArray,pbstr) BEGIN_SA_LOOP() CComBSTR s; s = pbstr[INDEX_SA]; // s now contains the item at the current position in the array // ... END_SA_LOOP(); END_SA(); // (8 lines of code)Easy, huh? Just an include file and a new set of macros...
Let's see what the different macros are doing...
宏定义
BEGIN_SA_V(vArray, pvar)
启动宏部分并定义所需的局部变量。
vArray
是一个包含 Safearray 的 Variant,pvar
是在循环中用于数组中每个项的变量。BEGIN_SA(sa, pvar)
启动宏部分并定义所需的局部变量。
sa
是一个 Safearray,pvar
是在循环中用于数组中每个项的变量。END_SA()
结束宏部分。
BEGIN_SA_LOOP()
启动循环。
INDEX_SA
是迭代器变量,你可以使用 pvar[INDEX_SA]
访问当前项。END_SA_LOOP()
循环的结尾。
INDEX_SA
是循环内的迭代器变量(类型为
LONG
)。BREAK_SA()
可以在实际循环中使用它来中断循环,只要它没有出现在嵌套的 for 循环中。
QUIT_SA()
如果计划在循环内退出方法,则应使用此宏以确保 Safearray 已关闭。
SAFEARRAY_SA
如果想直接访问
SAFEARRAY
对象,则可以使用此宏。当 Safearray 存在于 Variant 中时很有用。演示
要测试宏,请测试包含的 VC++ 和 VB 项目,它们说明了 BEGIN_SA_V
和 BEGIN_SA
宏。
源和用法
只需包含 #include "safearray_macro.h"
,将文件包含在你的代码中并开始使用它。如果对其进行任何扩展/修改,请通知我!
玩得开心...
/WW