[转]com组件系列总结

举报
Amrf 发表于 2021/02/03 00:13:03 2021/02/03
【摘要】 codesteps上面的广告有点多,影响阅读,下面这段脚本去除下:function removeElementsByClass(cls){ for(var i=0;i<cls.length;i++){ let className = cls[i] var elements = document.getElementsByClassName(className); while(...

codesteps上面的广告有点多,影响阅读,下面这段脚本去除下:

function removeElementsByClass(cls){
	for(var i=0;i<cls.length;i++){
	let className = cls[i]
	    var elements = document.getElementsByClassName(className);
	    while(elements.length > 0){
	        elements[0].parentNode.removeChild(elements[0]);
	    }
    }
}
function removeElementsById(ids){
	for(var i=0;i<ids.length;i++){
		if(document.getElementById(ids[i])){
			document.getElementById(ids[i]).parentNode.removeChild(document.getElementById(ids[i]))
		}	
	}

}
removeElementsByClass(['google-auto-placed','sidebar','adsbygoogle','related-posts','postauthor'])
removeElementsById(['site-header','comments',
  'commentsAdd','site-footer','cookie-notice' ])


https://codesteps.com/2014/02/28/com-creating-a-com-component-using-cpp-part-1/

COM – Creating a COM Component using C++ – IUnknown interface

COM (Component Object Model) is a platform-independent, distributed and object-oriented technology developed by Microsoft to create re-usable software components and enables software components to communicate.

COM enables interaction between objects through interfacesInterfaces are core concepts to build COM components. An interface contains function prototypes not the function implementations. COM interfaces are strongly typed and every interface has its own unique interface identifier (called GUID – Globally Unique IDentifier). Component developers must provide interface implementation and associate the implementation with interfaces.

COM Component expose the interfaces to COM Clients (those are going to use COM Components) or another COM Components. COM Clients will call the methods in interfaces and because of the association between interfaces and interface implementations, methods defined in COM Components will execute.

COM components can be created with variety of programming languages. In this article we are going to create a simple COM component using C++ programming language. As this concept is difficult to understand, we are going to explain this in series of articles; instead of a single article.

Before going to start implementing a COM component, lets have a look at basic interface IUnknown.

IUnknown interface

This is the core interface and must be implemented as part of every interface. IUnknown interface has 3 methods, two of them (AddRef and Release methods) are used for reference counting and QueryInterface method is used to retrieve pointer to object’s interfaces. Reference count controls the life of the object. When no references to the object, object should be destroyed.

Now the time for implementation.

Step (1). The first step is define an interface using Interface Definition Language (IDL) and save it in .idl file. Each interface in an IDL file contains interface header and body. The interface header contains attributes and the interface body contains interface methods. See below:

// Hello.idl : IDL source for IHello
//

import "unknwn.idl";

[
	uuid(2BEFC176-884D-4B33-A9FB-B0F86F2699A5),
	version(1.0)
]
interface IHello : IUnknown
{
	[id(1)] HRESULT SayHello([in] BSTR message);
};
  • Define an interface IHello using IDL language and save the file as “Hello.idl” file.
  • IUnknown interface is defined in “unknwn.idl” file. So, imported it into “Hello.idl” file; because this file is using IUnknown interface.
  • Inside interface header:
  • Inside interface body, define SayHello function. This function takes one argument (a string) and display the message.

Step (2). Now compile “Hello.idl” file using Microsoft’s MIDL compiler. Type the following at command prompt.

midl Hello.idl

MIDL compiler compiles “Hello.idl” file and generate the following files.

  • Hello.h – This is the header file contains the type definitions and function declarations for the interfaces.
  • Hello_i.c – The interface ID file. This file contains the IIDs and CLSIDs for every interface defined in IDL file. For eg: IID_IHello is defined in this file.
  • Hello_p.c – Proxy/Stub code contains in this file. Proxy/Stub code is used for marshaling. Marshaling is the process of packaging and unpackaging parameters between the remote procedure calls.
  • dlldata.c – Contains information to build and register a proxy/stub DLL.

Next article we will look into defining a component based on these MIDL generated files.

**

https://codesteps.com/2014/03/07/com-creating-a-com-component-using-c-part-2/

COM – Creating a COM Component using C++ – IUnknown interface definition

This is the series of articles explaining creating a COM component using C++. In our previous article, we have defined an interface IHello and compiled the IDL file using Microsoft’s MIDL compiler.

Now we are going to define a COM Component using C++. Remember that the all the interfaces defined in an IDL file must be implemented.

Step (1). Derive a C++ class from IHello interface. Add necessary header files.

// HelloComponent.h
//
#include "Hello.h"
#include "Hello_i.c"

class CHelloComponent : public IHello
{
};

Step (2). Declare the class methods in .h file and implement those methods in .cpp file for maintainability. Add IHello and IUnknown interface method declarations into CHelloComponent class. IUnknown methods maintain object’s reference counting; to keep object reference count add a variable (for eg: m_cRef).

// HelloComponent.h
//
#include "Hello.h"
#include "Hello_i.c"

#include <iostream>

class CHelloComponent : public IHello
{
public:
	CHelloComponent() : m_cRef (1)
	{
	}
	~CHelloComponent()
	{
	}

	// -- IUnknown Methods
	ULONG STDMETHODCALLTYPE AddRef();
	ULONG STDMETHODCALLTYPE Release();
	HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppv);

	// -- IHello Method
	HRESULT STDMETHODCALLTYPE SayHello(BSTR message);

private:
	ULONG m_cRef;
};

Step (3). Lets implement the IUnknown methods first. AddRef and Release methods of IUnknown interface maintains the object’s reference counting to ensure the lifetime of the object. Once no reference are there for the object; object will be released from the memory. These things are not done automatically; we need to implement this functionality in AddRef and Release methods. These are the guidelines for IUnknown interface. Because this is an interface, implementation doesn’t exist itself. But whoever going to implement IUnknown interface, they should implement these methods.

ULONG CHelloComponent::AddRef()
{
	return (++m_cRef);
}

ULONG CHelloComponent::Release()
{
	if ( --m_cRef != 0 ) 
		return m_cRef; 

	delete this;
	return 0;
}

AddRef will increment and Release will decrement the reference count value by 1. Release method also releases the object from memory when the reference count is 0. This way we have achieved initial goal of IUnknown interface.

Step (4). Another important method of IUnknown interface is QueryInterface. This method retrieves the requested interface pointer to the callers. A component can implement multiple interfaces. This function should always return the appropriate interface pointer requested by the caller.

HRESULT CHelloComponent::QueryInterface(REFIID riid, LPVOID *ppv)
{
	if ( ( riid == IID_IHello ) || ( riid == IID_IUnknown ) )
	{
		*ppv = (void *) this;
		AddRef(); // -- Maintain the reference count
	}
	else
		*ppv = NULL;

	return (*ppv == NULL) ? E_NOINTERFACE : S_OK;
}

In this component IHello and IUnknown interfaces are implemented. If the requested interface pointer is either of this type, QueryInterface function will return the pointer to this component. Otherwise this returns, NULL pointer with E_NOINTERFACE return code.

Step (5). Now we have to implement IHello‘s SayHello method. This method simply takes a string as an argument and display the string on the console window.

HRESULT CHelloComponent::SayHello(BSTR message)
{
	_bstr_t bstrMessage = message;

	cout << bstrMessage << endl;

	return S_OK;
}

_bstr_t class is the helper class deals with BSTR data types. It internally maintains resource allocation and deallocation for BSTR data types or you can specify it through its parameter.

Step (6). Include the necessary files in HelloComponent.cpp file.

#include "HelloComponent.h"

// -- for _bstr_t
#include <comutil.h>

// -- for std namespace; for cout etc.,
using namespace std;

Step (7). Now compile HelloComponent.cpp from command prompt using Microsoft’s tool cl.exe.

cl HelloComponent.cpp /EHsc /c

The file HelloComponent.cpp will compile and it will generate an .obj file.

Now the HelloComponent is ready. But, this is not enough to deploy the component. We need to wrap the component into a DLL and register it into Windows registry to complete the deployment. We will discuss about these in our next articles.

**

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。