windows 将 VARIANT 转换为...?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/606527/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 12:06:08  来源:igfitidea点击:

Convert VARIANT to...?

c++windowsvb.netvisual-studio-2008com

提问by Aaron

Note:

笔记:

  • Attempting to invoke a method of an interface, of which the return type is _variant_t
  • 试图调用接口的方法,其返回类型为 _variant_t

Code:

代码:

_variant_t resultsDataString;

_bstr_t simObjectNames;

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

resultsDataString = pis8->GetSimObject (simObjectNames);

inline function illustratedbelow, contained in .tliFILE:

所示的内联函数,包含在.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);
}

Note:

笔记:

  • resultsDataStringis of structtagVARIANT:
    • VARTYPE vtis 9 (unsigned short)
    • IDispatchIDispatch interface pointer
  • resultsDataStringstructtagVARIANT
    • VARTYPE vt是 9(无符号短)
    • IDispatchIDispatch 接口指针

Question

  • How can I then convertor extractthe value?
  • Possible using VariantChangeType?
  • Another way?
  • 然后我如何转换提取值?
  • 可以使用VariantChangeType吗?
  • 其它的办法?

Edit:

编辑:

Note:

笔记:

  • Looking to transform the following, Visual Basic code to Visual C++

  • MFC or ATL, if need be

  • Ideally, pure C++

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

  • MFC 或 ATL,如果需要

  • 理想情况下,纯 C++

Visual basicequivalent:

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) & "*"

采纳答案by Aardvark

It appears you are using C++ as a COM client by relying on the VC++ compiler's built-in COM support. To make coding the client "easier" you've used #importto generate C++ wrapper classes that attempt to hide all the COM details from you - or at least make the COM details simpler. So you're notusing the COM SDK directly, but are using a client-side framework (I think of it like a light-weight COM-only framework akin to ATL or MFC).

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

Your example code, however, seems to be mixing the direct low-level COM SDK (VARIANTs, BSTR, SysAllocString) with the #importCOM framework (_variant_t, _bstr_t, XXXXPtr). COM from C++ is complicated at first - so in a perfect world I would suggest getting to know the basics of COM before going too far forward.

但是,您的示例代码似乎将直接的低级 COM SDK ( VARIANTs, BSTR, SysAllocString) 与#importCOM 框架 ( _variant_t, _bstr_t, XXXXPtr)混合在一起。C++ 中的 COM 一开始很复杂 - 所以在一个完美的世界中,我建议在走得太远之前先了解 COM 的基础知识。

However, if you just want something to work I would guessthis is #import-style-of-COM-clients version of the VB code you provided:

但是,如果您只是想要一些工作,我这是#import您提供的 VB 代码的 -style-of-COM-clients 版本:

_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;

}

UPDATE:
Documentation on #importThis makes using COM from C++ much easier, but is yet one other thing to learn...

更新:
关于#import这方面的文档使从 C++ 中使用 COM 变得更加容易,但又是另一件事要学习......

回答by crashmstr

Take a look at the MSDN docs for _variant_t

查看_variant_t的 MSDN 文档

There is a ChangeTypemethod as well as Extractors.

有一个ChangeType方法以及Extractors

Edit:Once you have an IDispatchpointer, you need to use QueryInterfaceto get a specific object type with members and methods, or use IDispatch::Invoke. You can look at the MSDN Docs for IDispatch. Either way, you need to know about the object type that is being returned by the IS8Simulation::GetSimObjectcall.

编辑:一旦你有了一个IDispatch指针,你需要使用QueryInterface来获取具有成员和方法的特定对象类型,或者使用IDispatch::Invoke. 您可以查看 MSDN Docs for IDispatch. 无论哪种方式,您都需要了解IS8Simulation::GetSimObject调用返回的对象类型。

Edit #2:Based on your VB code update, you want to use the same kind of code for C++, i.e. use the S8SimObjecttype in its C++ form (look in the generated .tlh file for _COM_SMARTPTR_TYPEDEF). Then you can directly do the same thing with CountContents. Otherwise, you would need to look up the CountContentsDISPID with IDispatch::GetIDsOfNamesand then call invoke.

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

回答by Roger Lipscombe

You don't have to convertthe _variant_t. It contains an IDispatchinterface pointer, so you can get it out like this:

您不必转换_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.
}

回答by chrish

There is a concept of "value" for an object (DISPID_VALUE).

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

Here is a codeproject.com articleon resolving VARIANTs that might help.

这是关于解决可能有帮助的变体的codeproject.com 文章