简体   繁体   English

在C ++中使用COM dll

[英]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: 特别:

  • Each interface in the COM library will have a smart pointer created for it. COM库中的每个接口都会为其创建一个智能指针。 This smartpointer is just the name of the interface with Ptr appended. 此smartpointer只是添加了Ptr的接口的名称。 In the code above, IMyInterfacePtr is a smart pointer for an IMyInterface reference. 在上面的代码中, IMyInterfacePtrIMyInterface引用的智能指针。 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用于创建类的实例并获取对该接口的引用。
  • The LIBID, IIDs and CLSIDs of the items in the COM library are automatically exposed with globals of the form LIBID__MyLib , IID_IMyInterface and CLSID_MyConcreteObject . COM库中各项的LIBID,IID和CLSID将自动以LIBID__MyLibIID_IMyInterfaceCLSID_MyConcreteObject形式的全局变量CLSID_MyConcreteObject This makes the CreateInstance call easy. 这使CreateInstance调用变得容易。
  • Unless you use 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). 非原始表单会引发异常并使用一些高级类型(_bstr_t,variant_t)。 I generally like to use the non-raw forms because it means I have to do less error checking. 我通常喜欢使用非原始表单,因为这意味着我必须减少错误检查。 But I also like exceptions, which many other C++ developers do not. 但是我也喜欢例外,许多其他C ++开发人员不喜欢。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM