注意:
_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 ++
视觉基本等效:
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) & "*"
看来你正在使用C ++作为一个COM客户端依靠VC ++编译器的内置COM支持。 为了让客户端更容易编码,你已经使用#import
生成C ++包装类,试图隐藏所有的COM细节,或者至少使COM细节更简单。 所以你不直接使用COM SDK,而是使用客户端框架(我认为它像一个类似于ATL或MFC的轻量级COM-only框架)。
但是,您的示例代码似乎是将直接低级别的COM SDK( VARIANT
s, BSTR
, SysAllocString
)与#import
COM框架( _variant_t
, _bstr_t
, XXXXPtr
) XXXXPtr
。 C ++的COM起初是很复杂的 – 所以在一个完美的世界里,我建议在走得太远之前先了解一下COM的基本知识。
但是,如果你只是想要一些工作,我猜这是你提供的VB代码的#import
-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; }
更新:
关于#import
文档这使得从C ++使用COM变得更容易,但还有一件事要学习…
看看_variant_t的MSDN文档
有一个ChangeType方法以及提取器 。
编辑:一旦你有一个IDispatch
指针,你需要使用QueryInterface
获取一个具有成员和方法的特定对象类型,或者使用IDispatch::Invoke
。 您可以查看IDispatch
的MSDN文档。 无论哪种方式,您都需要了解IS8Simulation::GetSimObject
调用返回的对象类型。
编辑#2:根据你的VB代码更新,你想使用相同类型的代码为C + +,即在其C + +形式使用S8SimObject
类型(请查看生成的_COM_SMARTPTR_TYPEDEF
文件_COM_SMARTPTR_TYPEDEF
)。 然后你可以直接用CountContents
做同样的事情。 否则,您需要使用IDispatch::GetIDsOfNames
查找CountContents
DISPID,然后调用invoke。
您不必转换 _variant_t
。 它包含一个IDispatch
接口指针,所以你可以像这样得到它:
if (v.vt == VT_DISPATCH) { IDispatchPtr pDispatch = v.pdispVal; // Do something with pDispatch. // eg assign it to a strongly-typed interface pointer. }
对象(DISPID_VALUE)有一个“值”的概念。
这是一个关于解析VARIANT的codeproject.com文章 ,可能有所帮助。