1、定义:COM进程内服务器是指在DLL(动态链接库)中实现的COM服务器,它被加载到使用它的客户端应用程序的进程空间中,与客户端程序运行在同一个进程内。
2、特点
高效性:由于进程内服务器与客户端在同一进程空间中运行,它们之间的通信就像普通函数调用一样快速,不需要跨越进程边界进行参数传递和结果返回,因此执行效率非常高。
共享资源:进程内服务器可以直接访问客户端进程的资源,如内存、句柄等,这使得在一些需要共享大量数据或频繁交互的场景下具有优势。
部署方便:进程内服务器以DLL的形式存在,只需将DLL文件复制到客户端应用程序所在的目录或系统目录下即可使用,无需像进程外服务器那样单独安装和配置可执行文件。
1、注册:进程内服务器必须在系统的注册表中进行注册,通常是在HKEY_CLASSES_ROOTCLSID键值下创建一个以服务器的GUID为名称的键,该键必须包含服务器的位置(DLL文件的路径)和线程模型等信息。
2、接口暴露:进程内服务器需要导出一个名为DllGetClassObject()的函数,这是COM库调用的第一个函数,用于获取服务器的类工厂对象,类工厂对象实现了IClassFactory接口,通过该接口可以创建服务器的具体实例。
3、对象创建:当客户端应用程序调用CoCreateInstance()函数创建COM对象时,COM库会根据注册表中的信息找到对应的进程内服务器DLL,并调用其DllGetClassObject()函数获取类工厂对象,然后通过类工厂对象的CreateInstance()方法创建具体的COM对象实例,并将其接口指针返回给客户端应用程序。
4、接口调用:客户端应用程序获得COM对象的接口指针后,就可以通过该接口调用进程内服务器提供的各种方法和服务,在调用过程中,由于客户端和服务器在同一进程内,所以可以直接进行函数调用和参数传递。
1、加载与卸载:当客户端应用程序第一次使用进程内服务器时,操作系统会将服务器DLL加载到客户端进程的地址空间中,当不再需要服务器时,COM库会调用DllCanUnloadNow()函数询问服务器是否可以卸载,如果服务器确定不再被使用时,可以返回S_OK让COM库将其从内存中卸载。
2、引用计数:COM对象采用引用计数的方式来管理其生命周期,每当客户端创建一个COM对象实例时,引用计数就会增加;当客户端释放一个COM对象实例时,引用计数就会减少,当引用计数降为零时,表示没有客户端再使用该COM对象,此时COM对象会自动销毁自己。
下面是一个简单的进程内服务器示例代码,展示了如何用C++编写一个基本的COM服务器:
文件名 | 代码内容 | |
SimpleCOMServer.h | “cpp “ | |
SimpleCOMServer.cpp | “cpp #include "SimpleCOMServer.h" “ | |
SimpleCOMServer.def | “cpp LIBRARY "SimpleCOMServer" “ | |
SimpleCOMServer.rgs | “cpp [module] “ | |
SimpleCOMServer.rc | “cpp IDRC "SimpleCOMServer.rc" “ | |
SimpleCOMServer.cpp | “cpp #define INITGUID | rclsid == &GUID_SimpleComServer) { ppv = new SimpleComServer(); } else { ppv = NULL; } return ppv ? S_OK : E_NOINTERFACE; } STDMETHODIMP HRESULT DllCanUnloadNow() { return g_uDllRefCount > 0 ? S_FALSE : S_OK; } STDMETHODIMP HRESULT DllRegisterServer() { return RegisterServer(TRUE); } STDMETHODIMP HRESULT DllUnregisterServer() { return RegisterServer(FALSE); } int g_uDllRefCount = 0; int main() { CoInitialize(NULL); HRESULT hr = CoRegisterClassObject(&GUID_SimpleComServer, CLSCTX_INPROC_SERVER, NULL, DllGetClassObject, &g_uDllRefCount); if (FAILED(hr)) { CoUninitialize(); return -1; } WaitForSingleObject(GetCurrentProcess(), INFINITE); CoUninitialize(); return 0; }“ |
initguid.h | “cpp // This header is typically generated by the MIDL compiler based on the .idl file. It contains the definitions of the CLSID and IID values used in the server. “ | |
SimpleCOMServer.idl | “cpp import "oaidl.idl"; “ |
1、什么是COM进程内服务器?
答:COM进程内服务器是指在DLL中实现的COM服务器,它被加载到使用它的客户端应用程序的进程空间中,与客户端程序运行在同一个进程内,这种服务器类型具有高效性和资源共享等优点,适用于轻量级的小型服务器场景。
2、如何创建一个简单的COM进程内服务器?
答:创建一个简单的COM进程内服务器需要以下几个步骤:
定义COM接口:使用MIDL或其他工具定义COM接口,包括接口的方法和参数。
实现接口:在C++类中实现COM接口的方法,包括IUnknown接口的三个方法(AddRef、Release、QueryInterface)以及自定义的接口方法。
编写DllGetClassObject函数:该函数用于返回类工厂对象的实例,类工厂对象负责创建COM对象。
注册COM服务器:在系统的注册表中注册COM服务器的CLSID、程序ID等信息。
编译和生成DLL文件:使用编译器将源代码编译生成DLL文件,并将DLL文件注册到系统中。