COM中的安全数组SAFEARRAY、与在VC++(VARIANT) C#(object)中调用

转载 2012年03月24日 10:51:20

最近在做WEBGIS项目,要调用以前一些VC的DLL,所以使用COM进行封装,在C#中传数组头痛了几天,今天终于调试出来了。
由于COM中不能直接使用数组,所以经常使用到SAFEARRAY与VARIANT的转换

SAFEARRAY* pSA;
SAFEARRAYBOUND aDim[1]; //定义安全数组维数
aDim[0].lLbound=0;
aDim[0].cElements=2; //一维数组的元素数
pSA=SafeArrayCreate(VT_R8,1,aDim); //创建类型为DOUBLE的数组
ASSERT(pSA);
long aLong[1];
for(unsigned long l=aDim[0].lLbound;l<(aDim[0].lLbound+aDim[0].cElements);l++)

{
DOUBLE vTmp;
vTmp=0.2*l;
aLong[0]=l;
SafeArrayPutElement(pSA,aLong,&vTmp); //插入元素
}
将SafeArray转成VARIANT

VARIANT var;
VARTYPE vt;
VariantInit(&var);
SafeArrayGetVartype(pSA,&vt);
var.vt = VT_ARRAY|VT_VARIANT;
var.parray=pSA;

COM中将VARIANT 转成 SafeArray
STDMETHODIMP CZStation::GetDStation(VARIANT* vStaList, DOUBLE* SUM){
DOUBLE* pValue=NULL;
SAFEARRAY* pArray=var.parray;
SafeArrayAccessData(pArray,(void**)&pValue);//
long Low(0),High(0);

获取数组的高位和低位
SafeArrayGetLBound(pArray,1,&Low);
SafeArrayGetUBound(pArray,1,&High);
LONG i;

DOUBLE SUM = 0;
for(i=Low; i<High-Low+1; i++)
{
  *SUM += pValue[i];

}
return S_OK;
}

C#中调用COM
ZStation zst = new ZStationClass(); double dSta; double[] dlist = new double[2]; dlist[0] = 5.0; dlist[1] = 10.0; object vstalsit = dlist; dSta = zst.GetDStation(ref vstalsit);
VC++中调用COM
SAFEARRAY* pSA;
SAFEARRAYBOUND aDim[1];
aDim[0].lLbound=0;
aDim[0].cElements=2;
pSA=SafeArrayCreate(VT_R8,1,aDim);
ASSERT(pSA);
long aLong[1];
for(unsigned long l=aDim[0].lLbound;l<(aDim[0].lLbound+aDim[0].cElements);l++) {
DOUBLE vTmp;
vTmp=0.2*l;
aLong[0]=l;
SafeArrayPutElement(pSA,aLong,&vTmp);
}

CoInitialize(NULL);
double dsta;
CLSID clsid;
CLSIDFromProgID(OLESTR("ZGISCOM.ZStation"),&clsid);
CComPtr<IZStation> pStation;
pStation.CoCreateInstance(clsid);
double vv = pStation->GetDStation(&var);
pStation.Release();
CoUninitialize();

在COM中使用SafeArrayAccessData与SafeArrayGetElement函数,VC++调用没问题,C#调用出现问题比较让人费解,如果是WINAPP,使用前者正常,后者出现异常,而在ASP.NET中后者正常,前者出现异常。。。。。

C# 如何生成SafeArray(VBarray) 以及Javascript Array.

过去我用VC写的WebBrowser和JS交互时,遇到需要传递数组时, 总是使用SafeArray , 就是VBarray . 尽管我知道可以通过接口直接创建 JS array , 但是我们都知道vc...
  • norsd
  • norsd
  • 2009年12月21日 19:27
  • 4086

关于SAFEARRAY的,转载了篇文章,比较全

有个问题,64位COM组件调用32位COM组件(进程外)的时候: 32位组件里引入_IDTExtensibility2接口,64调用的时候失败; 如果不用引入的方法,而把接口函数写到IDL里,...
  • crybird
  • crybird
  • 2013年06月27日 15:25
  • 9010

SafeArray使用方法和函数解析

SafeArray处理函数      COM提供了一套API用于处理SafeArray。为了保证程序和SafeArray结构无关,程序中建立、读取、更改和释放SafeArray都应该通过这些API进...
  • RitMan
  • RitMan
  • 2016年06月10日 01:10
  • 2421

SAFEARRAY基本用法详解

SAFEARRAY讲解,自认为还是比较详细的。
  • u010204038
  • u010204038
  • 2014年07月24日 15:44
  • 3787

SAFEARRAY使用方法示例

SAFEARRAY使用方法示例 SAFEARRAY不是很好用,一些函数不太直观,一不小心就着了它的道。上次学习编写Google桌面插件时就遇到了麻烦,本来应该是vsa.vt = VT_ARRAY | ...
  • absurd
  • absurd
  • 2006年06月10日 18:41
  • 5067

VC/MFC中的CComboBox控件使用详解

CComboBox控件详解 CComboBox控件又称作组合框控件,其有三种形态可供选择,1.简单组合框(Simple)2.下拉组合框(Drop-down)3.下拉列表式组合框(Drop-down ...
  • daofengdeba
  • daofengdeba
  • 2013年10月27日 16:55
  • 2548

COleSafeArray

COleSafeArray类是用于处理任意类型和维数的数组的类。COleSafeArray是从OLE VARIANT结构派生而来的。OLE SAFEARRAY成员函数在可以通过COleSafeArra...
  • snjdju
  • snjdju
  • 2010年03月29日 09:04
  • 1407

COleSafeArray二维数组的使用注意

最近在做Excel的读写(OLE/COM),网上的参考虽多,但能用的比较少。 这次用到SetValu2的快速填充,其中使用COleSafeArray来做参数的转换。 碰到一个Bug,特此记录。(OLE...
  • baidu_37503452
  • baidu_37503452
  • 2017年07月27日 18:15
  • 223

Variant输入出参数,ocx传递byte数组,safearray使用方法,vc写ocx在vb下调用

  • 2009年05月26日 11:37
  • 2.17MB
  • 下载

SAFEARRAY的使用

目录: SAFEARRAY使用实例 1 目录: 1 前言: 1 何谓SAFEARRAY: 1 创建SAFEARRAY: 2 方法一:使用SafeArrayAllocDescriptor在栈...
  • neverup_
  • neverup_
  • 2010年06月26日 11:36
  • 5483
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:COM中的安全数组SAFEARRAY、与在VC++(VARIANT) C#(object)中调用
举报原因:
原因补充:

(最多只允许输入30个字)