我需要使用COM库中的方法。我已导入.dll并复制了.tlh文件。我是C ++和COM的新手,在描述问题时可能会出现明显的错误。我正在尝试识别接口和方法,并学习如何实现它们。我相信“Open”,“Close”,“GetFileName”,“GetCreatorID”等都是方法,而IXRawfile是一个接口。这是.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
};
接下来是更多的调查员,直到我这样做。
#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 );
代码继续这样,然后添加以下内容。
//
// 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;
在许多类似的陈述之后,该程序与下一个陈述类似。
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 );
我使用以下页面来实现这一目标http://www.codeproject.com/Questions/202460/using-COM-dll-in-a-c-console-application,但我无法理解如何实现作者的第二个解决方案。我该怎么办?
答案 0 :(得分:0)
您的程序是否正在尝试创建在#import
的DLL中定义的COM对象的实例?这很容易。这是一个粗略的模式。假设你有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();
}
除非#import
语句中包含其他属性,否则#import
应为您创建所有这些工件。具体做法是:
Ptr
的接口的名称。在上面的代码中,IMyInterfacePtr
是IMyInterface
引用的智能指针。这些智能指针执行所有必要的AddRef
/ Release
/ QueryInterface
工作,并提供CreateInstance
来创建类的实例并获取对其上的接口的引用。 LIBID__MyLib
,IID_IMyInterface
和CLSID_MyConcreteObject
形式的全局变量自动公开。这使CreateInstance
电话变得容易。raw_interfaces_only
语句中使用#import
,否则接口的方法将自动包含在某些代码中,这些代码会在异常情况下抛出_com_error
。如果没有raw_interfaces_only
,您将获得大多数方法的两种形式 - 一种只包含方法名称,另一种方法名称以raw_
为前缀。 raw_
表单不会抛出任何异常并使用原始COM类型(例如BSTR,VARIANT)。非原始表单抛出异常并使用一些高级类型(_bstr_t,variant_t)。我通常喜欢使用非原始表单,因为这意味着我必须做更少的错误检查。但我也喜欢异常,许多其他C ++开发人员都没有。