I'm trying to call a registered COM interface (Inproc dll) in an Eclipse C++ environment (MinGW GCC toolchain). I therefore don't believe that I can simply import the dll typelib the way I typically would in Visual C++. I'm trying to define the interface myself to simplify the function calls rather than using Invoke.
The IDL for the interface out of oleview looks like:
uuid(9293C753-B073-11D2-BD89-0060978EEB9C),
helpstring("IXSequence Interface"),
dual
]
dispinterface IXSequence {
properties:
methods:
[id(0x00000001), helpstring("method Close")]
void Close();
[id(0x00000002), helpstring("method New")]
void New();
[id(0x00000003), helpstring("method Open")]
void Open(
BSTR FileName,
long ReadOnly);
[id(0x00000004), helpstring("method Save")]
void Save(
BSTR UserName,
BSTR Comment,
long Overwrite);
[id(0x00000005), helpstring("method SaveAs")]
void SaveAs(
BSTR FileName,
BSTR UserName,
BSTR Comment,
long Overwrite);
[id(0x00000006), propget, helpstring("property Header")]
VARIANT Header();
[id(0x00000007), propget, helpstring("property AuditDataCollection")]
VARIANT AuditDataCollection();
[id(0x00000008), propget, helpstring("property Samples")]
VARIANT Samples();
[id(0x00000009), propget, helpstring("property BracketType")]
XBracketTypes BracketType();
[id(0x00000009), propput, helpstring("property BracketType")]
void BracketType([in] XBracketTypes rhs);
[id(0x0000000a), propget, helpstring("property UserLabel")]
BSTR UserLabel(short Index);
[id(0x0000000a), propput, helpstring("property UserLabel")]
void UserLabel(
short Index,
[in] BSTR rhs);
[id(0x0000000b), propget, helpstring("property TrayConfiguration")]
BSTR TrayConfiguration();
[id(0x0000000b), propput, helpstring("property TrayConfiguration")]
void TrayConfiguration([in] BSTR rhs);
[id(0x0000000c), propget, helpstring("property FileName")]
BSTR FileName();
[id(0x0000000d), propget, helpstring("property NewFile")]
long NewFile();
};
I've attempted to define the interface in my own header file like this:
const GUID CLSID_XcalFiles = { 0x9293C754, 0xB073, 0x11D2, {0xBD, 0x89, 0x00, 0x60, 0x97, 0x8E, 0xEB, 0x9C } };
const IID IID_IXSequence = { 0x9293C753, 0xB073, 0x11D2, {0xBD, 0x89, 0x00, 0x60, 0x97, 0x8E, 0xEB, 0x9C } };
typedef enum {
XUnspecified = 0,
XOverlapped = 1,
XNonBracketed = 2,
XNonOverlapped = 3,
XOpen = 4
} XBracketTypes;
enum XSampleTypes
{
XSampleUnknown = 0,
XSampleBlank = 1,
XSampleQC = 2,
XSampleStdClear = 3,
XSampleStdUpdate = 4,
XSampleStdBracket = 5,
XSampleStdBracketStart = 6,
XSampleStdBracketEnd = 7,
XSampleProgram = 8,
XSampleNumbersOfDifferentTypes = 9
};
DECLARE_INTERFACE_(IXSequence, IDispatch)
{
//methods
STDMETHOD_(void, Close)(THIS)PURE;
STDMETHOD_(void, New)(THIS)PURE;
STDMETHOD_(void, Open)(THIS_ BSTR FileName, long ReadOnly)PURE;
STDMETHOD_(void, Save)(THIS_ BSTR UserName, BSTR Comment, long Overwrite)PURE;
STDMETHOD_(void, SaveAs)(THIS_ BSTR FileName, BSTR UserName, BSTR Comment, long Overwrite)PURE;
STDMETHOD_(VARIANT, GetHeader)(THIS)PURE;
STDMETHOD_(VARIANT, GetAuditDataCollection)(THIS)PURE;
STDMETHOD_(VARIANT, GetSamples)(THIS)PURE;
//properties
STDMETHOD_(XBracketTypes, BracketType)(THIS)PURE;
STDMETHOD_(void, BracketType)(THIS_ XBracketTypes rhs)PURE;
STDMETHOD_(BSTR, UserLabel)(THIS_ short Index)PURE;
STDMETHOD_(void, UserLabel)(THIS_ short Index, BSTR rhs)PURE;
STDMETHOD_(BSTR, TrayConfiguration)(THIS)PURE;
STDMETHOD_(void, TrayConfiguration)(THIS_ BSTR rhs)PURE;
STDMETHOD_(BSTR, FileName)(THIS)PURE;
STDMETHOD_(long, NewFile)(THIS)PURE;
};
This appears to work well for the method calls but not for the properties. When I attempt to call any of the property functions, I get access violations. It does however seem to work if I use something like
STDMETHOD(GetBracketType)(THIS_ XBracketTypes* rhs)PURE;
Does that make sense? Is there a better way to declare the properties for the COM interface so that I can use them like normal properties?
IDispatch::GetIDsOfNames()andIDispatch::Invoke(), they don't access the property getter/setter methods directly. So, when a script accessesobj.Propor callsobj.Method(), it is actually callingobj.GetIDsOfNames()to get the DispID ofProporMethod(raising an error if the DispID can't be found) and then callingobj.Invoke()with that DispID and appropriate flags and parameters as needed. - Remy Lebeau