将VARIANT转换为......?

时间:2009-03-03 14:17:03

标签: c++ windows vb.net visual-studio-2008 com

注意:

  • 尝试调用接口的方法,其返回类型为_variant_t

代码:

_variant_t resultsDataString;

_bstr_t simObjectNames;

simObjectNames = SysAllocString (L"TEST example 3");

resultsDataString = pis8->GetSimObject (simObjectNames);

内嵌功能图示,包含在 .tli 文件中:

inline _variant_t IS8Simulation::GetSimObject ( _bstr_t Name ) {
    VARIANT _result;
    VariantInit(&_result);
     HRESULT _hr = get_SimObject(Name, &_result);
   if (FAILED(_hr)) _com_issue_errorex(_hr, this, __uuidof(this));
    return _variant_t(_result, false);
}

注意:

  • resultsDataString属于 struct tagVARIANT
    • VARTYPE vt 是9(无符号短片)
    • IDispatch IDispatch接口指针

问题

编辑:

注意:

  • 希望将以下Visual Basic代码转换为Visual C ++

  • MFC或ATL,如果需要

  • 理想情况下,纯C ++

Visual basic 等效:

Public example1, example2 As SIMUL8.S8SimObject
Dim numberOfexamples As Variant
Dim resultString As Variant

Set example1 = MySimul8.SimObject("Example 1")
Set example2 = MySimul8.SimObject("Example 2")

numberOfexamples = example1.CountContents + example2.CountContents

resultString = CStr(numberOfexamples) & "*"

4 个答案:

答案 0 :(得分:2)

查看_variant_t

的MSDN文档

有一个ChangeType方法以及Extractors

编辑:获得IDispatch指针后,您需要使用QueryInterface获取包含成员和方法的特定对象类型,或使用IDispatch::Invoke 。您可以查看IDispatch的MSDN文档。无论哪种方式,您都需要了解IS8Simulation::GetSimObject调用返回的对象类型。

编辑#2:根据您的VB代码更新,您希望为C ++使用相同类型的代码,即在其C ++表单中使用S8SimObject类型(查看生成_COM_SMARTPTR_TYPEDEF的.tlh文件。然后你可以直接用CountContents做同样的事情。否则,您需要使用CountContents查找IDispatch::GetIDsOfNames DISPID,然后调用invoke。

答案 1 :(得分:2)

依靠VC ++编译器的内置COM支持,您似乎正在使用C ++作为COM客户端。为了使客户端编码“更容易”,您使用#import生成C ++包装类,尝试隐藏您的所有COM详细信息 - 或者至少使COM详细信息更简单。所以你直接使用COM SDK,但是正在使用客户端框架(我认为它就像一个类似于ATL或MFC的轻量级COM框架。)

但是,您的示例代码似乎是将直接低级COM SDK(VARIANT s,BSTRSysAllocString)与#import COM框架混合在一起( _variant_t_bstr_tXXXXPtr)。来自C ++的COM起初很复杂 - 所以在一个完美的世界里,我建议在走得太远之前先了解一下COM的基础知识。

但是,如果你只想要一些工作,我会 猜测 这是#import - 样式的COM客户端版本的VB代码你提供:

_variant_t example1Var;
_variant_t example1Var;
SIMUL8::S8SimObjectQIPtr example1; // I'm guessing at this type-name from the VB code
SIMUL8::S8SimObjectQIPtr example2;

example1Var = pis8->GetSimObject(_bstr_t(L"Example 1"));
example2Var = pis8->GetSimObject(_bstr_t(L"Example 2"));
if (example1Var.vt == VT_DISPATCH && example2Var.vt == VT_DISPATCH)
{
   // **UPDATE** to try to spoon feed the QI ptr...
   example1 = IDispatchPtr((IDispatch*)example1Var);
   example2 = IDispatchPtr((IDispatch*)example2Var);
   // Does this screw-up reference counting?

   int numberOfexamples = example1->CountContents + example2->CountContents;

}

<强>更新
Documentation on #import这使得使用C ++中的COM变得更加容易,但还有一件事要学习......

答案 2 :(得分:1)

您无需转换 _variant_t。它包含一个IDispatch接口指针,因此你可以这样得到它:

if (v.vt == VT_DISPATCH)
{
    IDispatchPtr pDispatch = v.pdispVal;
    // Do something with pDispatch.
    // e.g. assign it to a strongly-typed interface pointer.
}

答案 3 :(得分:0)

对象有一个“值”的概念(DISPID_VALUE)。

以下是解析可能有用的VARIANT的codeproject.com article