如何从VARIANT提出BSTR数组,也不知这样问对不对~~各位高手~~好心人请进来看看吧

hktl 2001-07-19 08:42:43
我程序是在网页里接受一个字符串数组
网页里的写法是
h[0]="hi"
h[1]="i"
h[2]="you"
hstr(h)

我的程序是这样接收的
STDMETHODIMP apinet::hstr(VARIANT *astr)
首先请各位高手看看我这样接收有没有错
程序是可以执行的
但我接收后
我要怎么得到[0]="hi"[1]="i"[2]="you"
我要是把VARIANT转成char* 或者bstr
得到的却是乱码
要是转成SAFEARRAY
转了以后我不知怎么得到[0]="hi"[1]="i"[2]="you"
请大家帮帮忙
弄了几天真的没办法了
麻烦一下各位了
谢谢
...全文
291 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
wyzegg 2001-07-21
  • 打赏
  • 举报
回复
针对你的问题我又回去写啦程序,下面的是调试通过的代码,你上面的疑问是这样的
0 1 2 3
0 w j k l
1 y c v n
上面的两维数组他是按C的调用法则的
int index[2]={2,1};
long data;
SafeArrayGetElement(pSafeArray,index,&data);
在data里回得到v;
下面的代码针对你的情况创建一个包含一个1维字符串数组的VARIANT值,然后读出结果,代码调试通过。可以用下面的 办法代替上面的办法。至于维数的获得可以参考前次的回答。

#include "stdafx.h"
#include "atlbase.h"

int main(int argc, char* argv[])
{
USES_CONVERSION;
HRESULT hr;
SAFEARRAYBOUND pSab[1];//一维数组
pSab[0].lLbound=0;
pSab[0].cElements=4;
SAFEARRAY *pSa;
VARIANT var;
pSa=SafeArrayCreate(VT_BSTR,1,pSab);//创建一维数组
if(pSa==NULL)
return -1;
long index;
index=0;
BSTR bstr=SysAllocString(L"hello world");
hr=SafeArrayPutElement(pSa,&index,bstr);
if (FAILED(hr))
return -1;
index=1;
bstr=SysAllocString(L"I");
hr=SafeArrayPutElement(pSa,&index,bstr);
if (FAILED(hr))
return -1;
index=2;
bstr=SysAllocString(L"love");
hr=SafeArrayPutElement(pSa,&index,bstr);
if (FAILED(hr))
return -1;
index=3;
bstr=SysAllocString(L"you");
hr=SafeArrayPutElement(pSa,&index,bstr);
if (FAILED(hr))
return -1;
var.vt=VT_BSTR|VT_ARRAY;
var.parray=pSa;//构造一个VARIANT
SAFEARRAY *pSafeArray=var.parray;
BSTR bstr1;
for(long i=0;i<4;i++)
{
SafeArrayGetElement(pSafeArray,&i,&bstr1);
printf(OLE2T(bstr1));
printf("\n");
}
/* 运行结果为
hello world
I
love
you*/
return 0;
}
masterz 2001-07-21
  • 打赏
  • 举报
回复
关键是怎么在javascript中访问variant类型包含的safearray. 有人知道吗,关注中
wyzegg 2001-07-21
  • 打赏
  • 举报
回复
运行网页,得到的文件d:\a.log内容
lLBound is 0
lUBound is 4
Array length is 4
VT value is 24588
第 1 个字符串是:i
第 2 个字符串是:love
第 3 个字符串是:vb
第 4 个字符串是:hello world

好啦请查收
关键不一样的是这个
SAFEARRAY *pSafeArray=*var.pparray


wyzegg 2001-07-21
  • 打赏
  • 举报
回复
下面是TestString.GetString的程序,
STDMETHODIMP CGetString::GetString(VARIANT var)//输入的参数没有用指针,和你的没有差别的
{
// TODO: Add your implementation code here
USES_CONVERSION;//用来转换BSTR的宏
HRESULT hr;
char log[255];
long lUBound=0,lLBound=0;
SAFEARRAY *pSafeArray=*var.pparray;//不一样的地方在这里其他的都是一样的
hr = SafeArrayGetLBound(pSafeArray, 1, &lLBound);
if(FAILED(hr))
return -1;
hr = SafeArrayGetUBound(pSafeArray, 1, &lUBound);
if(FAILED(hr))
return -1;
sprintf(log,"lLBound is %d",lLBound);
WriteLog(log);
sprintf(log,"lUBound is %d",lUBound);
WriteLog(log);
sprintf(log," Array length is %d",lUBound-lLBound);
WriteLog(log);
sprintf(log,"VT value is %d",var.vt);
WriteLog(log);
VARIANT varRet;
for(long i=0;i<lUBound-lLBound;i++)
{
SafeArrayGetElement(pSafeArray,&i,&varRet);
sprintf(log,"第 %d 个字符串是:%s",i+1,OLE2T(varRet.bstrVal));
//OLE2T可以把BSTR转换
WriteLog(log);//写进文件
}
return S_OK;
}

void CGetString::WriteLog(char * string)
{
FILE *fp;
if((fp=fopen("d:\\a.log","a+"))==NULL)
{
return;
}
fprintf(fp,"%s",string);
fprintf(fp,"%s","\n");
fclose(fp);
}
wyzegg 2001-07-21
  • 打赏
  • 举报
回复
兄弟,问题已经解决啦
下面是网页的文本
<html>
<body>
<script language="VBScript">
Set MyTest = CreateObject("TestString.GetString")
if err<>0 then
MsgBox("the com not properly installed on this PC!")
else
MsgBox("the com is installed on this PC!")
end if
dim h(4)
h(0)="i"
h(1)="love"
h(2)="vb"
h(3)="hello world"
MyTest.GetString(h)
MsgBox("sdgsd")
</script>
</body>
</html>
wyzegg 2001-07-21
  • 打赏
  • 举报
回复
最后是VT_ARRAY|VT_VARIANT | VT_BYREF
可以先得到维数,

VARIANT var;
SafeArrayGetElement(pSafeArray,&i,&var);
剩下的就简单啦

wyzegg 2001-07-20
  • 打赏
  • 举报
回复
inside COM里有SAFEARRAY用法的详细介绍,这个一定要用SAFEARRAY的啦

HRESULT hr;
VARIANT var;//这是你得到的包含字符串数组的VAR
SAFEARRAY *psa=var.parray;
long lUBound,lLBound,cElements;
hr = SafeArrayGetLBound(psa, 1, &lLBound);
if(FAILED(hr))
return ;
hr = SafeArrayGetUBound(psa, 1, &lUBound);
if(FAILED(hr))
return ;
long i, j, min;
BSTR bstrTemp;
BSTR HUGEP *pbstr;
hr = SafeArrayAccessData(psa, (void HUGEP* FAR*)&pbstr);
if (FAILED(hr))
return;
cElements = lUBound-lLBound+1; //得到维数
for (i = 0; i < cElements-1; i++)
{
min = i;
for (j = i+1; j < cElements; j++)
{
if (wcscmp(pbstr[j], pbstr[min]) < 0)
min = j;
}

// Swap array[min] and array[i].
bstrTemp = pbstr[min];
pbstr[min] = pbstr[i];
pbstr[i] = bstrTemp;

}

SafeArrayUnaccessData(psa);
hktl 2001-07-20
  • 打赏
  • 举报
回复
wait
hktl 2001-07-20
  • 打赏
  • 举报
回复
wyzegg(蛋)
能否在oicq连络一下
关于这个问题
我还要请教你
到现在这一句SafeArrayGetLBound(psa, d, &lLBound);
还是执行不过
我的qq是41233280
hktl 2001-07-20
  • 打赏
  • 举报
回复
wyzegg(蛋)在吗
greensleeve 2001-07-20
  • 打赏
  • 举报
回复
终于找到了
hktl 2001-07-20
  • 打赏
  • 举报
回复
很谢谢这么详细的回答
有个疑问
bstrTemp = pbstr[min];
pbstr[min] = pbstr[i];
pbstr[i] = bstrTemp;
这些代码是把pbstr里面东东换来换去
到底有什么用啊

还有我刚才试了一下
可以编释但不能执行
在hr = SafeArrayGetLBound(psa, 1, &lLBound);这里时出错
我是把你写的代码copy到我的函数下的
只删除了VARIANT var
和把SAFEARRAY *psa=var.parray;
换成SAFEARRAY *psa=astr.parray;
应该没有改动到你的代码的
hktl 2001-07-19
  • 打赏
  • 举报
回复
各位高手
麻烦一下

3,245

社区成员

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

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