VARIANT真麻烦,怎么用?

ad 2000-08-11 02:15:00
我写了一个ActiveX控件,有一个方法从控件中取得字符串,增加控件的方法时不能在参数表中指定BYTE *或LPSTR,而只能通过返回VARIANT的方法,但VARIANT实在复杂,下面的代码是我编写的,用起来有问题,请高手指点!

//控件中
VARIANT CFaCommCtrl::ReadData(short nMax)
{
VARIANT vaResult;
VariantInit(&vaResult);

//...
vaResult.vt = VT_ARRAY and VT_UI1; //表示是单字节数组
vaResult.parray = new SAFEARRAY;
vaResult.parray->cDims = 1; //一维
vaResult.parray->fFeatures = FADF_AUTO;
vaResult.parray->pvData = new BYTE[nMax];//存放数据
vaResult.parray->cbElements = l;
//...

return vaResult;
}

应用程序中

//m_c 是CFaCommCtrl类
VARIANT v = m_c.ReadData(10);
for(int i=0;i<v.parray->cbElements;i++){
s[i] = ((char *)v.parray->pvData)[i];
}
s[i]='\0';

执行上述过程时没有问题,但使用UpdateData(..)时出错(m_c对应CFaCommCtrl控件),去掉UpdateData(..)一切正常,但程序退出时出错,且错误窗口始终关不掉,Studio提示访问违法。
...全文
513 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
hjcao_wei 2000-08-23
  • 打赏
  • 举报
回复
BSTR 实际上是BYTE字节流,我在com server 与client中用BSTR传递过大对象,没有问题

如果是MFC ColeVariant _variant_
如果是ATL CComVarint

我编组建与控件时用 ATL
mytulip 2000-08-23
  • 打赏
  • 举报
回复
I watch
铜戈 2000-08-18
  • 打赏
  • 举报
回复
mfc吗?
为什么不用COleVarian呢
VARIANT aaaa::aaaaaaaa()
{
return CleVariant("aaa").detach();
}
还可以用宏
USES_CONVERSION

W2A("aaaa")返回宽字符
?2?有很多查msdn

另外注意控件里的数据返回到外面药用detach()(有的话)方法将内存释放交给调用方不然
退出调用方法局部变量自动释放,外部的道将士无效指针,很容易非法操作
这也是为什么com对象返回值必须是指针

ad 2000-08-18
  • 打赏
  • 举报
回复
恳请大虾关注!
ad 2000-08-12
  • 打赏
  • 举报
回复
感谢各位提示和指教,不过需要更正的是,我的控件需要返回的数据是二进制字节流,而不是字符串,看来用BSTR是行不通的,而ACTIVEX不能在方法的参数表使用(BYTE *)类型,只有使用VARIANT了,而且只能作为函数的返回值,不能列在参数表中,显然这样做效率低下。
zzh请注意,我在帖子中写出的代码对吗?上级程序获得返回值并作了处理后,是否需要delete[] vaResult.parray->pvData ?
zzh 2000-08-11
  • 打赏
  • 举报
回复
有什么麻烦的,对于不同的数据类型,你进行不同的转换不就得了。增加控件时可以使用变体形数据类型。
renk 2000-08-11
  • 打赏
  • 举报
回复
STDMETHODIMP和S_OK是ATL中的.MFC中可以返回BSTR,不知你用的是什么版本的VC,我在VC中可以生成以下代码:
BSTR CXcccfCtrl::ReadData()
{
CString strResult;
// TODO: Add your dispatch handler code here

return strResult.AllocSysString();
}
Tiangz 2000-08-11
  • 打赏
  • 举报
回复
看一下这段代码,是我以前使用MSSocket接收的发送数据的代码:
void CMainFrame::OnSocketDataArrival (long bytesTotal )
{
int nLength=bytesTotal;//将要接收的字节数;
CString str(' ',nLength); //分配内存
VARIANT varData,* pvarData=&varData;

pvarData->vt = VT_BSTR;
pvarData->bstrVal = str.AllocSysString(); //在MSDN中仔细看看这个函数和下面的
//SysFreeString
GPSSocket.GetData (pvarData,varType,varLength);
memcpy(lpStr,pvarData->bstrVal ,bytesTotal*2);
//将VARIANT类型转换为LPSTR
SysFreeString(pvarData->bstrVal);

下面这端代码是将Unicode转换为ASCII的,代码不全,你如感兴趣,咱们再讨论
for (nEnd=0;nEnd<=nLength;nEnd++) //将16位Unicode字符串转换为8位ASCII字符串
{ memcpy(lpStrSub+nEnd,lpStr+(2*nEnd),1);
if ( * ( lpStr+(2*nEnd) ) ==';')
break;
}
memcpy(lpStrSub+nEnd+1,&cNull,1);

ad 2000-08-11
  • 打赏
  • 举报
回复
不对!看来renk没有用MFC写过ACTIVEX控件。写控件时根本没有STDMETHODIMP和S_OK的定义。因为不能在参数表中使用BSTR,而BSTR*又不对,所以我改用VARIANT,但怎么正确使用呢?
renk 2000-08-11
  • 打赏
  • 举报
回复
好象应该这样:
STDMETHODIMP CFaCommCtrl::ReadData(BSTR *pVal)
{
//xxxxxx
return S_OK;
}
一般返回值都用HRESULT吧
VARIANT 中也可以放BSTR,用VT_BSTR

ad 2000-08-11
  • 打赏
  • 举报
回复
MSCOMM控件用的就是VARIANT,我该怎么用呢?
ad 2000-08-11
  • 打赏
  • 举报
回复
但是,我需要返回内容,可以这样写吗:BSTR ReadData(len) 或short ReadData(BSTR )?
增加方法时参数只能是(BSTR *).
renk 2000-08-11
  • 打赏
  • 举报
回复
字符串应该用BSTR

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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