SAFEARRAY(安全数组)使用详解

SAFEARRAY(安全数组)使用详解

一,何谓SAFEARRAY(安全数组)

winddows操作系统与使用 SAFEARRAY 定义。 下列 SAFEARRAY 结构是 SAFEARRAY 典型、 一般定义:

typedef struct FARSTRUCT tagSAFEARRAY {
  
  
   unsigned short cDims;       // 安全数组的大小
   
   
   unsigned short fFeatures;   //安全数组的标记,取值见下表
   
   
                        
  
  
#if defined(WIN32)  //如果在windows系统上
   
   
   unsigned long cbElements;   //安全数组元素的大小
   
   
                           //不包括安全数组数据的大小  
   
   
   unsigned long cLocks;  // 被锁定次数 
   
   
                        
  
  
#else
  
  
   unsigned short cbElements;
  
  
   unsigned short cLocks;
  
  
   unsigned long handle;      // 仅用在 Macintosh 系统上
   
   
#endif
  
  
   void HUGEP* pvData;             // 数据指针
   
   
   SAFEARRAYBOUND rgsabound[1];      //安全数组的下界,元素数, 结构见下说明
   
   
} SAFEARRAY;
  
  

 

 typedef struct tagSAFEARRAYBOUND {
  
  
   unsigned long cElements;// 元素数
   
   
   long lLbound;// 数组的下界
   
   
} SAFEARRAYBOUND;
  
  

 

fFeatures;  //安全数组的标记

说明

FADF_AUTO 0x0001

在栈上创建数组

FADF_STATIC 0x0002

在堆上创建数组

FADF_EMBEDDED 0x0004

在结构中创建

FADF_FIXEDSIZE 0x0010

不能改变数组大小

FADF_RECORD 0x0020

记录容器

FADF_HAVEIID 0x0040

IID 身份标记 数组

FADF_HAVEVARTYPE 0x0080

VT 类型数组

FADF_BSTR 0x0100

BSTR数组

FADF_UNKNOWN 0x0200

IUnknown* 数组

FADF_DISPATCH 0x0400

IDispatch* 数组

FADF_VARIANT 0x0800

VARIANTs数组

FADF_RESERVED 0xF0E8

余留,将来使用


  
  
   
    
  
  
 
  
  

Microsoft Windows 2000 WindowsXP 等操作系统系统使用整个 Win32API 因此, 是运行 Windows 2000 WindowsXP, 计算机上之后处理条件指令, Oaidl.h 文件与以下示例代码中可能定义 SAFEARRAY

typedef struct tagSAFEARRAY { 
  
  
   USHORT cDims;
  
  
   USHORT fFeatures;
  
  
   ULONG cbElements;
  
  
   ULONG cLocks;
  
  
   PVOID pvData;
  
  
   SAFEARRAYBOUND rgsabound[ 1 ];
  
  
} SAFEARRAY;
  
  

Oaidl.h 文件, SAFEARRAYBOUND 是如以下示例代码中定义一个结构:

typedef struct tagSAFEARRAYBOUND {

   unsigned long cElements;

   long lLbound;

} SAFEARRAYBOUND;

Oaidl.h 文件还包含对于, 可用于访问 SAFEARRAY 函数原型。

,什么情况下使用

1在使用vc编写COM组件的时候,需要一次传递很多的数据时,使用SAFEARRAY就会很方便

2VisualBasic C 之间或在 VisualBasic VisualC++, 之间传递数组或字符串,用 C C++ ATL 创建 DLL时用SAFEARRAY

 

三,使用实例

 

  1使用SafeArrayAllocDescriptor在栈上创建一维数组

   //创建SAFEARRAY数组,每个元素为long型,该数组是一维数组

   long nData[10]={1,2,3,4,5,6,7,8,9,10};

 

   SAFEARRAY* pArray=NULL;

   HRESULT hr=SafeArrayAllocDescriptor(1,&pArray);//创建SAFEARRAY结构的对象

   pArray->cbElements=sizeof(nData[0]);

   pArray->rgsabound[0].cElements=10;

   pArray->rgsabound[0].lLbound=0;

   pArray->pvData=nData;

   pArray->fFeatures=FADF_AUTO|FADF_FIXEDSIZE;//FADF_AUTO指定在栈上分配数据,并且大小不可以改变(固定为10

  

   //访问SAFEARRAY数组

   long* pValue=NULL;

   SafeArrayAccessData(pArray,(void**)&pValue);//取得数据存到指针pValue

   long Low(0),High(0);

   hr=SafeArrayGetLBound(pArray,1,&Low);//维数索引从1开始

   hr=SafeArrayGetUBound(pArray,1,&High);//维数索引从1开始

 

   SafeArrayUnaccessData(pArray);

   SafeArrayDestroy(pArray);

这种方法在栈上分配数组元素所占的空间,即nData数组所用的空间

2vc++创建dll, VisualBasicdll中传数组

Vc++中创建dll工程StdDLL,把下边函数复制到cpp

 long __declspec (dllexport) __stdcall Func2(SAFEARRAY **ppsaMyArray) 
  
  
      {
  
  
                   HRESULT hr;
  
  
                   HUGEP byte * plData;
  
  
      hr = SafeArrayAccessData(*ppsaMyArray, (void HUGEP* FAR*)&plData);//取得数组数据
   
   

  
  
   
    
  
  
    
  
  
      byte baa;
  
  
        baa=plData[0];//第一个数据
   
   
      
  
  
      SafeArrayUnaccessData(*ppsaMyArray);//取消数据访问
   
   

  
  
   
    
  
  
     
  
  

  
  
   
    
  
  
      SafeArrayDestroy(*ppsaMyArray);//销毁
   
   
             return 2;
  
  
      }
  
  

将以下文本追加到 StdDLL.def 文件中现有文本:

Func2

VisualBasic中创建工程

添加以下声明代码,

Private Declare Function Func2 Lib"C:/StdDLL/Debug/StdDLL.dll" (MyArray() As Long) As Long ‘注意文件路径和你机器的一致

添加 Command1命令按钮,把以下代码附加到 Command 1 _ Click 事件过程中

 

Dim Result As Long
  
  
Dim MyArrayOfLongs(3) As Long
  
  

  
  
   
    
  
  
MyArrayOfLongs(0) = 0
  
  
MyArrayOfLongs(1) = 1
  
  
MyArrayOfLongs(2) = 2
  
  

  
  
   
    
  
  
Result = Func2(MyArrayOfLongs())
  
  
MsgBox ("Func2 returned " & Result)
  
  
四,注意问题
   
   

1  在堆上创建SAFEARRAY数组

2  一方创建,一方回收

3  接收方不可以修改SAFEARRAY的数据,只能读或者销毁


  
  
   
    源代码 
   
   http://www.ls-rj.cn
  
  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值