如何向safearray放入BSTR类型的数据

crazygod 2003-08-20 08:36:06
CString strValue[32];
for(int i = 0; i < 32; i++)
strValue[i] = ...;

COleVariant varValue;

现在要把strValue数组中的CString值写到varValue.pArray中
请各位达人指点!
...全文
310 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
crazygod 2003-08-21
  • 打赏
  • 举报
回复
masterz(MS MVP):
非常感谢!
有几个疑问:
1.
在第一个例程中
long aLong[1];
// iterate over array adding VARIANTs of type VT_BSTR
for (long l= aDim[0].lLbound; l< (aDim[0].cElements + aDim[0].lLbound); l++) {
VARIANT vOut;
VariantInit(&vOut);
vOut.vt= VT_BSTR; // set type
ltoa(l,buffer,10); // convert long to ANSI string value
vOut.bstrVal= ::SysAllocString(A2W(buffer)); // system wide "new"
aLong[0]= l; // set index value
if (hr= SafeArrayPutElement(pSA, aLong, &vOut)) { // "correctly" copies VARIANT
VariantClear(&vOut); // release BSTR from memory on error
SafeArrayDestroy(pSA); // does a deep destroy on error
return hr;
}
VariantClear(&vOut); // does a deep destroy of source VARIANT
} // end iteration

如果将if (hr= SafeArrayPutElement(pSA, aLong, &vOut))
改为 if (hr= SafeArrayPutElement(pSA, &l, &vOut))
可以吗?如果不可以,为什么?

2.如果我用以下的方法来做,有什么问题吗?
SAFEARRAYBOUND Bound;
long lIndex;

Bound.cElements = 32;
Bound.lLbound = 0;

varValue.Clear();
varValue.vt = VT_ARRAY | VT_BSTR;
varValue.pArray = SafeArrayCreate(VT_BSTR, 1, &Bound);

for(int i = 0; i < 32; i++)
{
_bstr_ b = strValue[i].AllocSysString;
SafeArrayPutElement (varTmp[i].parray, <emp, b.copy());
SysFreeString(b);
}

VariantClear(&varValue);

开始时我使用的是SafeArrayPutElement (varTmp[i].parray, <emp, &b);
但是总是不能将数据传入,非常郁闷。
一直到昨天晚上才找到一个帖子,上面用到了b.copy(),试着用了一下,居然可以了
因此大虾能不能指点一下个中道理呢?
主要就是safearray和BSTR类型的数据好像在内存管理方面比较搞人!

谢谢!
masterz 2003-08-20
  • 打赏
  • 举报
回复
COleSafeArray saRet;
DWORD numElements[2];
numElements[0]= m_iNumRows; //Number of rows in the range.
numElements[1]= m_iNumCols; //Number of columns in the range.

if(m_bFillWithStrings)
{
saRet.Create(VT_BSTR, 2, numElements);
}
else
{
saRet.Create(VT_R8, 2, numElements);
}

//Fill the SAFEARRAY.
long index[2];
long iRow;
long iCol;

for(iRow=0;iRow<=m_iNumRows-1;iRow++)
{
for(iCol=0;iCol<=m_iNumCols-1;iCol++)
{
index[0] = iRow;
index[1] = iCol;
if(m_bFillWithStrings) //Fill with Strings.
{
VARIANT v;
CString s;
VariantInit(&v);
v.vt = VT_BSTR;
s.Format("r%dc%d", iRow, iCol);
v.bstrVal = s.AllocSysString();
saRet.PutElement(index, v.bstrVal);
SysFreeString(v.bstrVal);
VariantClear(&v);
}
else //Fill with Numbers.
{
double d;
d = (iRow*1000) + iCol;
saRet.PutElement(index, &d);
}
}
}

//Set the range value to the SAFEARRAY.
range.SetValue(COleVariant(saRet));
saRet.Detach();
masterz 2003-08-20
  • 打赏
  • 举报
回复
USES_CONVERSION; // enables use of ATL conversion macro A2W
char buffer[20]; // used to store ANSI string
HRESULT hr= S_OK;

// Create SafeArray of VARIANT BSTRs
SAFEARRAY *pSA;
SAFEARRAYBOUND aDim[1]; // a one dimensional array
aDim[0].lLbound= 0; // Visual Basic arrays start with index 0
aDim[0].cElements= 10;
pSA= SafeArrayCreate(VT_VARIANT,1,aDim); // create a 1D SafeArray of VARIANTS
if (pSA != NULL) {
long aLong[1];
// iterate over array adding VARIANTs of type VT_BSTR
for (long l= aDim[0].lLbound; l< (aDim[0].cElements + aDim[0].lLbound); l++) {
VARIANT vOut;
VariantInit(&vOut);
vOut.vt= VT_BSTR; // set type
ltoa(l,buffer,10); // convert long to ANSI string value
vOut.bstrVal= ::SysAllocString(A2W(buffer)); // system wide "new"
aLong[0]= l; // set index value
if (hr= SafeArrayPutElement(pSA, aLong, &vOut)) { // "correctly" copies VARIANT
VariantClear(&vOut); // release BSTR from memory on error
SafeArrayDestroy(pSA); // does a deep destroy on error
return hr;
}
VariantClear(&vOut); // does a deep destroy of source VARIANT
} // end iteration
}
// clean up here only if you do not return SafeArray as an [out, retval]
SafeArrayDestroy(pSA); // again does a deep destroy
masterz 2003-08-20
  • 打赏
  • 举报
回复
USES_CONVERSION; // enables use of ATL conversion macro A2W
char buffer[20]; // used to store ANSI string
HRESULT hr= S_OK;

// Create SafeArray of VARIANT BSTRs
SAFEARRAY *pSA;
SAFEARRAYBOUND aDim[1]; // a one dimensional array
aDim[0].lLbound= 0; // Visual Basic arrays start with index 0
aDim[0].cElements= 10;
pSA= SafeArrayCreate(VT_VARIANT,1,aDim); // create a 1D SafeArray of VARIANTS
if (pSA != NULL) {
long aLong[1];
// iterate over array adding VARIANTs of type VT_BSTR
for (long l= aDim[0].lLbound; l< (aDim[0].cElements + aDim[0].lLbound); l++) {
VARIANT vOut;
VariantInit(&vOut);
vOut.vt= VT_BSTR; // set type
ltoa(l,buffer,10); // convert long to ANSI string value
vOut.bstrVal= ::SysAllocString(A2W(buffer)); // system wide "new"
aLong[0]= l; // set index value
if (hr= SafeArrayPutElement(pSA, aLong, &vOut)) { // "correctly" copies VARIANT
VariantClear(&vOut); // release BSTR from memory on error
SafeArrayDestroy(pSA); // does a deep destroy on error
return hr;
}
VariantClear(&vOut); // does a deep destroy of source VARIANT
} // end iteration
}
// clean up here only if you do not return SafeArray as an [out, retval]
SafeArrayDestroy(pSA); // again does a deep destroy
利用activeX实现matlab和vb的混合编程-vb_matlab_activeX.rar      想要在vb里面直接执行matlab的代码吗?想省去编译dll文件的代码吧?     好的,activeX帮你实现这样的功能.     activeX简介: ActiveX部件是Microsoft公司提供的一种用于模块集成的新的协议,它是Visual Basic工具箱的扩充部分。在程序中加入ActiveX后,它将成为开发和运行环境的一部分。Matlab实现了ActiveX自动化服务支持,在Visual Basic下通过ActiveX自动化接口可将Matlab作为Visual Basic语言的一个ActiveX部件调用,实现VB与MATLAB间的无缝集成,该方式比较适合C/S模式,具有自动化程度高、效率高、占用资源少、数据交换能力强等优点,大大缩短了程序开发周期,优化了系统性能。 activeX运用: 使用ActiveX部件,首先必须获得Matlab ActiveX对象在系统注册表中定义的名字─Matlab.Application。在VB中创建ActiveX对象的代码如下: Dim Matlab as Object. Set Matlab = CreateObject Matlab.Application对象主要有3个函数,具体如下: (1) BSTR Execute([in]BSTR Command)方法 接受单一的字符串(Command), MATLAB将运行命令及结果作为一个字符串返回。用于执行一个合法的MATLAB命令; (2) PutFullMatrix方法 void PutFullMatrix pr, [in] SAFEARRAY pr, [in] SAFEARRAY pi ) 将一个指定变量名的一维或二维数组(mxArray放入工作空间。 (3) GetFullMatrix方法 void GetFullMatrix pr, [in] SAFEARRAY pr, [in] SAFEARRAY pi ) 通过GetFullMatrix方法,从指定的工作空间检索一个完整的一维或二维的实型或虚型数组(mxArray),其实部和虚部分别存放到两个单独的Double型数组中。[2] 通过这三种方法,可以方便地利用Matlab执行命令,从VB向Matlab中输送数据或者从Matlab中获取数据。 实例举例: 1.程序功能: 给出三个变量:x=0:0.05*pi:10*pi;y=sin;z=cos 并且做出x,y,z的三维图形,并在vb的image窗口中显示,             下面是vb程序的界面,只有一个command按钮和image图片框    程序界面.jpg 下面是程序的运行结果: 程序运行结果.jpg 2.代码 Dim Matlab As Object Dim Result1 As String Dim Result2 As String Dim Result3 As String Private Sub Command1_Click() Result1 = Matlab.Execute;z=cos") Result2 = Matlab.Execute") Result3 = Matlab.Execute") Image1.Picture = Clipboard.GetData() Call Matlab.quit '退出Matlab End Sub Private Sub Form_Load() Set Matlab = CreateObject End Sub 3.程序源程序: vb_matlab_activeX.rar

3,245

社区成员

发帖
与我相关
我的任务
社区描述
ATL,Active Template Library活动(动态)模板库,是一种微软程序库,支持利用C++语言编写ASP代码以及其它ActiveX程序。
社区管理员
  • ATL/ActiveX/COM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧