简体   繁体   中英

Add Method to COM Interface

I created a ATL COM dll workspace with VS2008. It has generated MyCom.idl interface. Does it provide any easy way to add a method to this interface?

Yes, there is an option to do that.

在此输入图像描述

It is not that hard to do this without a wizard. I learned that adding COM interface methods the hard way because I was too lazy to look it up in MSDN , so I looked closely at other COM interfaces and experimented by adding properties, methods, etc.

First of all there are two drawbacks when using the wizard, especially when editing existing COM interfaces. First it is slow, especially if you have a large component with dozens of interfaces. I sit in front of a quite decent workstation and opening the wizard and completeing the two or three steps takes longer than adding the method by hand to the IDL, .h and .cpp file.

Second is that when using different Visual Studio and thus different Wizard versions there will be generated c++ dirt like multiple public-statements without any need and stuff like that. However I recommend that you act like the wizard in order to not confuse it further if the next programmer uses the wizard again - which will increase confusion and in the end leading to increased file sizes, unreadable class declarations and longer compile times. Just insert the same type of methods or macros at the same place the wizard does.

So maybe you might find useful what I found out so long. You can find a lot more details in the article " Understanding IDL " which is quite old, but provides essential basics which I will not mention here though.

The IDL file holds all interface definitions your component will export. So if you want to add a method you need to find the corresponding interface definition which is introduced by the "interface" keyword and a name which usally starts with a capital I. The interface is preceded by some annotations surrounded by [ and ] which I will not explain for the sake of simplicity. When using Visual Studio IDL keywords will be highlighted correctly. This is how a typical interface might look like:

[
  object,
  uuid(0B2499FA-0D73-488C-B961-03FB8327485C),
  dual,   helpstring("IMyInterface Interface"),
  pointer_default(unique)
]
interface IMyInterface : IDispatch {
    // ... methods and properties
};

Now let us assume the IMyInterface contains one method only and you want to add a similar second one:

[id(1), EXCLUDE_FROM_HELP] HRESULT DoSomething([in] long newVal, [out, retval] long* pRetVal);

Again there are annotations within the [ ] brackets. When adding a new method increase the id annotations value. Also precede the parameters with the [in] annotation for input parameters, [out] for parameters which will contain the methods results. If there is only one result you may want to use a method which uses the result as return value. Then use the [out, retval] annotation.

So when adding such a method copy the line above, increase the ID and changed the methods name and adapt the parameters accordingly.

Note that the [out] parameters always must be a pointer. There are several reasons for this, the most obvious one is that [in, out] is possible too, thus the result for a parameter should be written to the same memory address inside the component so it is possible to pass it back to the caller easily. Also note that the "real" return value should be an HRESULT handle, which will indicate the success or failure of the method.

Now let us look inside the C++ header. I assume you will find the correct file and place by yourself.

STDMETHOD(DoSomething)(/*[in]*/ long newVal, /*[out, retval]*/ long* pRetVal);

The STDMETHOD macro takes care of the result value which is HRESULT and the calltype. The annoations are not valid here but for clarification of the intended usage within the IDL file they are added as comments. These comments are optional though. Be careful to use the same datatypes as inside the IDL file.

STDMETHODIMP CMyClass::DoSomething( /*[in]*/ long newVal, /*[out, retval]*/ long* pRetVal )
{
    AFX_MANAGE_STATE(AfxGetStaticModuleState());

    long result = GetTheResultValueFromSomewhere();
    *pRetVal = result;

    return S_OK;
}

The STDMETHODIMP is a different macro than in the header. Basically it does the same though. Important is the AFX_MANAGE_STATE macro if you want to use resources within an MFC dialog for instance. Imagine the value in the example above is determined by prompting the user. Read about it in the Technical Tips blog post .

Understanding the IDL mechanisms will help you as soon as errors occur which do not necessarily refer to a problem in your logic but the interface. It will also allow you to understand what the interface actually does, which will help you avoding errors when using the wizard so I encourage anyone to read at least some basic information about it.

如果您在类视图中展开idl以右键单击特定类并使用“添加方法”或“添加属性”,则应该有一个选项,该向导将引导您完成将该方法添加到您的界面和相关实现的小向导。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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