[英]Using a COM dll in C++
I need to use methods from a COM library. 我需要使用COM库中的方法。 I have imported the .dll and copied the .tlh file bellow.
我已导入.dll并复制了以下.tlh文件。 I am a C++ and COM newbie and will likely make obvious errors in describing the problem.
我是C ++和COM新手,在描述问题时可能会犯明显的错误。 I am trying to identify the interfaces and methods and learn how to implement them.
我正在尝试确定接口和方法,并学习如何实现它们。 I believe "Open", "Close", "GetFileName", "GetCreatorID", and the like are methods, and IXRawfile is an interface.
我相信“打开”,“关闭”,“ GetFileName”,“ GetCreatorID”等是方法,而IXRawfile是接口。 Here is the .tlh
这是.tlh
namespace MSFileReaderLib {
//
// Forward references and typedefs
//
struct __declspec(uuid("f0c5f3e3-4f2a-443e-a74d-0aabe3237494"))
/* LIBID */ __MSFileReaderLib;
enum __MIDL___MIDL_itf_XRawfile2_0000_0000_0001;
enum __MIDL___MIDL_itf_XRawfile2_0000_0000_0002;
enum __MIDL___MIDL_itf_XRawfile2_0000_0000_0003;
enum __MIDL___MIDL_itf_XRawfile2_0000_0000_0004;
enum MS_PacketTypes;
enum MS_Polarity;
enum MS_ScanData;
enum MS_Dep;
enum MS_Wideband;
enum MS_SourceCID;
enum MS_SourceCIDType;
enum MS_MSOrder;
enum MS_ScanType;
enum MS_TurboScan;
enum MS_IonizationMode;
enum MS_Corona;
enum MS_Detector;
enum MS_PrecursorEnergy;
enum MS_Multiplex;
enum MS_Param_A;
enum MS_Param_B;
enum MS_Param_F;
enum MS_Param_K;
enum MS_Param_R;
enum MS_Param_V;
enum MS_Activations;
struct MS_FullMSOrderPrecursorInfo;
struct MS_MassRange;
struct MS_ScanEvent;
struct MS_ScanIndex;
struct MS_ScanIndex64;
struct MS_UVScanIndex;
struct MS_DataPeak;
struct MS_PrecursorInfo;
struct __declspec(uuid("11b488a0-69b1-41fc-a660-fe8df2a31f5b"))
/* dual interface */ IXRawfile;
struct __declspec(uuid("55a25ff7-f437-471f-909a-d7f2b5930805"))
/* dual interface */ IXRawfile2;
struct __declspec(uuid("19a00b1e-1559-42b1-9a46-08a5e599edee"))
/* dual interface */ IXRawfile3;
struct __declspec(uuid("e7cf6760-11cd-4260-b5b0-fce2ad97547b"))
/* dual interface */ IXRawfile4;
struct __declspec(uuid("06f53853-e43c-4f30-9e5f-d1b3668f0c3c"))
/* dual interface */ IXRawfile5;
struct __declspec(uuid("55ea38b7-5419-4be4-9198-3e4d78e64632"))
/* dual interface */ IXVirMS;
enum MS_DataTypes;
struct __declspec(uuid("7ff032a3-fb2a-46ef-a579-039da67c0aaa"))
/* dual interface */ IXVirMS64;
struct MS_ScanDataStruct;
struct __declspec(uuid("796cb3fe-c696-4afe-b719-18246f38a740"))
/* dual interface */ IXVirUV;
struct /* coclass */ MSFileReader_XRawfile;
struct /* coclass */ MSFileReader_XVirMS;
struct /* coclass */ MSFileReader_XVirUV;
//
// Smart pointer typedef declarations
//
_COM_SMARTPTR_TYPEDEF(IXRawfile, __uuidof(IXRawfile));
_COM_SMARTPTR_TYPEDEF(IXRawfile2, __uuidof(IXRawfile2));
_COM_SMARTPTR_TYPEDEF(IXRawfile3, __uuidof(IXRawfile3));
_COM_SMARTPTR_TYPEDEF(IXRawfile4, __uuidof(IXRawfile4));
_COM_SMARTPTR_TYPEDEF(IXRawfile5, __uuidof(IXRawfile5));
_COM_SMARTPTR_TYPEDEF(IXVirMS, __uuidof(IXVirMS));
_COM_SMARTPTR_TYPEDEF(IXVirMS64, __uuidof(IXVirMS64));
_COM_SMARTPTR_TYPEDEF(IXVirUV, __uuidof(IXVirUV));
//
// Type library items
//
enum __MIDL___MIDL_itf_XRawfile2_0000_0000_0001
{
MS_TRAILER_NOT_AVAILABLE = -1
};
This is followed by more enumerators until I get to this. 接下来是更多的枚举数,直到我了解为止。
#pragma pack(pop)
struct __declspec(uuid("11b488a0-69b1-41fc-a660-fe8df2a31f5b"))
IXRawfile : IDispatch
{
//
// Wrapper methods for error-handling
//
HRESULT Open (
_bstr_t szFileName );
HRESULT Close ( );
HRESULT GetFileName (
BSTR * pbstrFileName );
HRESULT GetCreatorID (
BSTR * pbstrCreatorID );
HRESULT GetVersionNumber (
long * pnVersion );
HRESULT GetCreationDate (
DATE * pCreationDate );
HRESULT IsError (
long * pbIsError );
The code continues like this and then adds the following. 代码继续这样,然后添加以下内容。
//
// Raw methods provided by interface
//
virtual HRESULT __stdcall raw_Open (
BSTR szFileName ) = 0;
virtual HRESULT __stdcall raw_Close ( ) = 0;
virtual HRESULT __stdcall raw_GetFileName (
BSTR * pbstrFileName ) = 0;
virtual HRESULT __stdcall raw_GetCreatorID (
BSTR * pbstrCreatorID ) = 0;
virtual HRESULT __stdcall raw_GetVersionNumber (
long * pnVersion ) = 0;
virtual HRESULT __stdcall raw_GetCreationDate (
DATE * pCreationDate ) = 0;
virtual HRESULT __stdcall raw_IsError (
long * pbIsError ) = 0;
After many similar statements the program does something similar with this next statement. 在执行了许多类似的语句之后,程序对该下一条语句执行了类似的操作。
struct __declspec(uuid("55a25ff7-f437-471f-909a-d7f2b5930805"))
IXRawfile2 : IXRawfile
{
//
// Wrapper methods for error-handling
//
HRESULT GetLabelData (
VARIANT * pvarLabels,
VARIANT * pvarFlags,
long * pnScanNumber );
HRESULT GetNoiseData (
VARIANT * pvarNoisePacket,
long * pnScanNumber );
I used the following page to get this far http://www.codeproject.com/Questions/202460/using-COM-dll-in-ac-console-application , but I am having trouble understanding how to implement the author's second solution. 我使用以下页面介绍了到目前为止的内容http://www.codeproject.com/Questions/202460/using-COM-dll-in-ac-console-application ,但是我在理解如何实现作者的第二个解决方案时遇到了麻烦。 How should I proceed?
我应该如何进行?
Is your program attempting to create an instance of a COM object that is defined in the DLL that you are #import
ing? 您的程序是否正在尝试创建要在
#import
的DLL中定义的COM对象的实例? This is very easy. 这很容易。 Here's a rough pattern.
这是一个粗略的模式。 Suppose you have some.dll that contains a class called MyObject that implements IMyInterface.
假设您有some.dll,其中包含一个名为MyObject的类,该类实现了IMyInterface。
#import "some.dll"
void main()
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
// if you use smart pointers, it's best to have an
// inner scope to ensure that all your objects are
// released before calling CoUninitialize
{
IMyInterfacePtr o;
o.CreateInstance(CLSID_MyObject);
o->SomeMethod();
}
CoUninitialize();
}
Unless instructed otherwise with additional attributes on the #import
statement, the #import
should create all these artifacts for you. 除非在
#import
语句中另有说明,否则#import
应该为您创建所有这些工件。 Specifically: 特别:
Ptr
appended. Ptr
的接口的名称。 In the code above, IMyInterfacePtr
is a smart pointer for an IMyInterface
reference. IMyInterfacePtr
是IMyInterface
引用的智能指针。 These smartpointers do all the necessary AddRef
/ Release
/ QueryInterface
work and also provide a CreateInstance
for creating an instance of a class and getting a reference to an interface on it. AddRef
/ Release
/ QueryInterface
工作,并且还提供CreateInstance
用于创建类的实例并获取对该接口的引用。 LIBID__MyLib
, IID_IMyInterface
and CLSID_MyConcreteObject
. LIBID__MyLib
, IID_IMyInterface
和CLSID_MyConcreteObject
形式的全局变量CLSID_MyConcreteObject
。 This makes the CreateInstance
call easy. CreateInstance
调用变得容易。 raw_interfaces_only
on the #import
statement, the methods of the interfaces will be automatically wrapped in some code that throws _com_error
s in the cases of exceptions. #import
语句上使用raw_interfaces_only
,否则接口的方法将自动包装在某些代码中,这些代码在发生异常的情况下会引发_com_error
。 Without raw_interfaces_only
, you'll get 2 forms of most methods -- one that just has the method name and one that has the method name with raw_
prepended. raw_interfaces_only
,您将获得大多数方法的两种形式-一种仅具有方法名称,另一种具有具有raw_
前缀的方法名称。 raw_
forms don't throw any exceptions and use the raw COM types (eg BSTR, VARIANT). raw_
表单不会引发任何异常,而是使用原始COM类型(例如BSTR,VARIANT)。 The non-raw forms throw exceptions and use some advanced types (_bstr_t, variant_t).
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.