C++ 如何遍历 SAFEARRAY **

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12484109/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:19:06  来源:igfitidea点击:

How to iterate through SAFEARRAY **

c++comsafearray

提问by TrustyCoder

how to iterate through C++ safearray pointer to pointer and access its elements.

如何遍历指向指针的 C++ 安全数组指针并访问其元素。

I tried to replicate the solution posted by Lim Bio Liong http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/022dba14-9abf-4872-9f43-f4fc05bd2602but the strangest thing is that the IDL method signature comes out to be

我试图复制 Lim Bio Liong 发布的解决方案 http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/022dba14-9abf-4872-9f43-f4fc05bd2602但最奇怪的是 IDL方法签名出来是

HRESULT __stdcall GetTestStructArray([out] SAFEARRAY ** test_struct_array);

instead of

代替

HRESULT __stdcall GetTestStructArray([out] SAFEARRAY(TestStruct)* test_struct_array);

Any ideas?

有任何想法吗?

thanks in advance

提前致谢

回答by Zdeslav Vojkovic

Safearrays are created with SafeArrayCreateor SafeArrayCreateVector, but as you ask about iterating over a SAFEARRAY, let's say you already have a SAFEARRAY returned by some other function. One way is to use SafeArrayGetElementAPI which is especially convenient if you have multidimensional SAFEARRAYs, as it allows, IMO, a bit easier specifying of the indices.

Safearrays 是用SafeArrayCreateor创建的SafeArrayCreateVector,但是当您询问迭代 SAFEARRAY 时,假设您已经有一个由其他函数返回的 SAFEARRAY。一种方法是使用SafeArrayGetElementAPI,如果您有多维 SAFEARRAY,它会特别方便,因为它允许 IMO 更轻松地指定索引。

However, for vectors (unidimensional SAFEARRAY) it is faster to access data directly and iterate over the values. Here's an example:

但是,对于向量(一维 SAFEARRAY),直接访问数据并迭代这些值会更快。下面是一个例子:

Let's say it's a SAFEARRAY of longs, ie. VT_I4

假设它是longs的 SAFEARRAY ,即。VT_I4

// get them from somewhere. (I will assume that this is done 
// in a way that you are now responsible to free the memory)
SAFEARRAY* saValues = ... 
LONG* pVals;
HRESULT hr = SafeArrayAccessData(saValues, (void**)&pVals); // direct access to SA memory
if (SUCCEEDED(hr))
{
  long lowerBound, upperBound;  // get array bounds
  SafeArrayGetLBound(saValues, 1 , &lowerBound);
  SafeArrayGetUBound(saValues, 1, &upperBound);

  long cnt_elements = upperBound - lowerBound + 1; 
  for (int i = 0; i < cnt_elements; ++i)  // iterate through returned values
  {                              
    LONG lVal = pVals[i];   
    std::cout << "element " << i << ": value = " << lVal << std::endl;
  }       
  SafeArrayUnaccessData(saValues);
}
SafeArrayDestroy(saValues);

回答by Roman R.

MSDN SafeArrayGetElement functiongives you a code snippet on using SafeArrayGetElementto obtain individual object to array.

MSDN SafeArrayGetElement 函数为您提供了一个SafeArrayGetElement用于获取单个对象到数组的代码片段。

SAFEARRAYstructureand SafeArray*functions explain the available API.

SAFEARRAY结构SafeArray*函数解释了可用的 API。

In ATL/MFC project you would want to use wrapper classes e.g. CComSafeArrayto make things simpler and easier. See Simplifying SAFEARRAY programming with CComSafeArrayon this.

在 ATL/MFC 项目中,您可能希望使用包装类,例如CComSafeArray使事情更简单更容易。有关此内容,请参阅使用 CComSafeArray 简化 SAFEARRAY 编程