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
  • 4005

读取SafeArray数据

网上介绍SafeArray使用C#读取的很少。所以特贴此代码,供需要的人使用。         按钮事件: // clear TextBox edtAc...

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

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

VC++中经常用到的类型转换(总结)

1、VARIANT转COleSafeArray、  COleSafeArray转BYTE型数组 在串口通信的OnCommMscomm()事件中会涉及到这两种类型转换,比如: VARIANT var...

COM组件,字符串数组的传递

前阵子做作业,需要用到COM。在ATL下开发简单的COM组件很简单,唯一的难点在于复杂参数的传递。比如说字符串数组,需要学习SAFFARRAY,bstr以及VARIANT的用法。     下面贴出代...

SAFEARRAY(安全数组)使用详解

SAFEARRAY(安全数组)使用详解一,何谓SAFEARRAY(安全数组):winddows操作系统与使用 SAFEARRAY 定义。 下列 SAFEARRAY 结构是 SAFEARRAY 典型、 ...

使用VARIANT传递数组的方法及步骤

在使用COM/DCOM写组件时经常要传递数组,一般比如SHORT,LONG等指针可以直接传递相应的指针,但是当遇到需要传递BYTE数组就有问题了,COM不支持BYTE类型参数,传递BYTE数组也就无从...

COM组件开发笔记--字符串数组的传递

COM编程的好处就是可以跨语言,我们公司是用C#做开发的,所以用C++去开发COM组件就可以弥补图形渲染性能上的不足。但COM组件也有它的缺点,就是COM接口本身的调用开销比较大,所以我总结了,使用C...
  • Sayesan
  • Sayesan
  • 2013年12月09日 15:33
  • 1076

COM组件开发笔记--字符串数组的传递

COM编程的好处就是可以跨语言,我们公司是用C#做开发的,所以用C++去开发COM组件就可以弥补图形渲染性能上的不足。但COM组件也有它的缺点,就是COM接口本身的调用开销比较大,所以我总结了,使用C...
  • Sayesan
  • Sayesan
  • 2013年11月27日 17:04
  • 779

在COM中使用数组参数

关键字:DCOM、数组、自定义类型、Marshal、SafeArray、ICollection  本文讲述在COM的接口中使用数组作为参数的三种方法。它们分别是:数组指针、SafeArray和ICol...
  • wcyoot
  • wcyoot
  • 2011年06月23日 09:40
  • 4727
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:COM中的安全数组SAFEARRAY、与在VC++(VARIANT) C#(object)中调用
举报原因:
原因补充:

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