用c++实现com组件示例

简单实现基于C++的COM组件创建与DLL封装 简单实现基于C++的COM组件创建与DLL封装,包括组件、COM、COM组件、DLL等基本概念与关系,使用C++进行COM组件创建与DLL封装调用等的简单实现。 阅读详情

 

1、 创建一个win32  dll应用类型项目工程。

2、  添加ComTest.h及ComTest.cpp文件,并在ComTest.h头文件包含Unknwn.h头文件

3、  用guid.exe生成一个接口IID及com对象类CLSID

代码如下:

//ComTest.h

#pragma once

 

#include <Unknwn.h>

 

EXTERN_C const CLSID CLSID_TestObject;

EXTERN_C const CLSID IID_ObjectInterface;

 

MIDL_INTERFACE("DE5A091A-EF80-4bd3-8AEB-CB20B879A2F1")

IObjectInterface :public IUnknown

{

   virtual void __stdcall TestMethod() PURE;

};

//ComTest.cpp

#include "StdAfx.h"

#include "ComTest.h"

 

 

EXTERN_C const CLSID CLSID_TestObject  =

{0xa33e547a, 0x8a95, 0x4118, {0x86, 0xa, 0x46, 0xb2, 0x3c, 0x6d, 0x40, 0xbd}};

EXTERN_C const CLSID IID_ObjectInterface  =

{0xde5a091a, 0xef80, 0x4bd3, {0x8a, 0xeb, 0xcb, 0x20, 0xb8, 0x79, 0xa2, 0xf1}};

 

 

 

4、  添加CTestObject类,这个类必须实现IObjectInterface接口,并且必须实现IUnkown接口的三个函数。

代码如下

//TestObject.h

#pragma once

#include "ComTest.h"

 

class CTestObject:public IObjectInterface

{

public:

CTestObject(void);

public:

~CTestObject(void);

 

public:

HRESULT __stdcall QueryInterface( REFIID riid,void **ppvObject);

ULONG   __stdcall AddRef( void);

ULONG   __stdcall Release( void);

public:

void   __stdcall TestMethod();

private:

int m_nRef;

};

 //TestObject.cpp

#include "StdAfx.h"

#include "TestObject.h"

#include <iostream>

using namespace std;

 

CTestObject::CTestObject(void)

:m_nRef(0)

{

}

 

CTestObject::~CTestObject(void)

{

}

 

HRESULT  CTestObject::QueryInterface( REFIID riid,void **ppvObject)

{

  if (riid==__uuidof(IUnknown))

  {

     *ppvObject = (IUnknown*)this;

     ((IUnknown*)*ppvObject)->AddRef();

     return S_OK;

  }

  else if (riid==__uuidof(IObjectInterface))

  {

     *ppvObject = (IObjectInterface*)this;

     ((IObjectInterface*)*ppvObject)->AddRef();

     return S_OK;

  }

  else

  {

     *ppvObject = NULL;

     return E_NOINTERFACE;

  }

}

ULONG    CTestObject::AddRef( void)

{

  m_nRef++;

  return m_nRef;

}

ULONG    CTestObject::Release( void)

{

  m_nRef--;

  if (m_nRef==0)

  {

     delete this;

  }

  return m_nRef;

}

 

void CTestObject::TestMethod()

{

  cout<<"this is my com test!"<<endl;

}

 

5、 必须要为com对象创建一个工厂类,该工厂类还必须实现IClassFactory接口。

当我们调用CoCreateInstance函数创建com对象的时候,com标准库会调用DllGetClassObject获取工厂对象,再由工厂对象调用其成员函数CreateInstance来创建我们需要的com对象。

代码如下:

  //.h

#pragma once

#include <Unknwn.h>

 

extern ULONG    g_LockNumber;

class CTestObjectFactory:public IClassFactory

{

protected:

  int m_nRef;

public:

  CTestObjectFactory(void);

public:

  ~CTestObjectFactory(void);

public:

  HRESULT __stdcall QueryInterface( REFIID riid,void **ppvObject);

  ULONG   __stdcall AddRef( void);

  ULONG   __stdcall Release( void);

public:

  HRESULT STDMETHODCALLTYPE CreateInstance(IUnknown *pUnkOuter,REFIID riid,void **ppvObject);

  HRESULT STDMETHODCALLTYPE LockServer(BOOL fLock) ;

};

//.cpp

#include "StdAfx.h"

 

#include "ComTest.h"

#include "TestObject.h"

#include "TestObjectFactory.h"

 

CTestObjectFactory::CTestObjectFactory(void)

:m_nRef(0)

{

}

 

CTestObjectFactory::~CTestObjectFactory(void)

{

}

 

HRESULT  CTestObjectFactory::QueryInterface( REFIID riid,void **ppvObject)

{

   if (riid==__uuidof(IUnknown))

   {

      *ppvObject = (IUnknown*)this;

      ((IUnknown*)*ppvObject)->AddRef();

      return S_OK;

   }

   else if (riid==__uuidof(IClassFactory))

   {

      *ppvObject = (IClassFactory*)this;

      ((IClassFactory*)*ppvObject)->AddRef();

      return S_OK;

   }

   else

   {

      *ppvObject = NULL;

      return E_NOINTERFACE;

   }

}

ULONG    CTestObjectFactory::AddRef( void)

{

   m_nRef++;

   return m_nRef;

}

ULONG    CTestObjectFactory::Release( void)

{

   m_nRef--;

   if (m_nRef==0)

   {

      delete this;

   }

   return m_nRef;

}

HRESULT CTestObjectFactory::CreateInstance(IUnknown *pUnkOuter,REFIID riid,void **ppvObject)

{

   if (NULL != pUnkOuter)

      return CLASS_E_NOAGGREGATION;

   DT(L"Enter CreateInstance...");

   CTestObject *pObj=NULL;

   pObj = new CTestObject();

   if (pObj==NULL)

   {

      *ppvObject = NULL;

      return E_OUTOFMEMORY;

   }

   HRESULT hr = pObj->QueryInterface(riid,ppvObject);

   if (FAILED(hr))

   {

      DT(L"Failed to Create TestObj!");

      delete pObj;

   }

   return hr;

}

HRESULT CTestObjectFactory::LockServer(BOOL fLock)

{

   if (fLock)

   {

      g_LockNumber++;

   }

   else

      g_LockNumber--;

   return NOERROR;

}

 

6、  有了com对象类和工厂类后,我们要想办法将我们的com对象信息写到注册表中去,

一般要写入以下信息:

HKEY_LOCAL_MACHINE/SOFTWARE/Classes/CLSID/{A33E547A-8A95-4118-860A-46B23C6D40BD}

HKEY_LOCAL_MACHINE/SOFTWARE/Classes/CLSID/{A33E547A-8A95-4118-860A-46B23C6D40BD}/InprocServer32

HKEY_LOCAL_MACHINE/SOFTWARE/Classes/CLSID/{A33E547A-8A95-4118-860A-46B23C6D40BD}/ProgID

HKEY_LOCAL_MACHINE/SOFTWARE/Classes/TestCom.Object

HKEY_LOCAL_MACHINE/SOFTWARE/Classes/TestCom.Object/CLSID

 

7、 要添加导出文件,添加下面四个函数的实现:

LIBRARY   "Component"

 

EXPORTS

DllGetClassObject PRIVATE

DllRegisterServer PRIVATE

DllUnregisterServer PRIVATE

DllCanUnloadNow PRIVATE

 

有关这四个函数的实现,参考如下代码:

// Registry.cpp

 

#include "StdAfx.h"

 

#include <objbase.h>

#include <assert.h>

#include "Registry.h"

 

////////////////////////////////////////////////////////

//

// Internal helper functions prototypes

//

//   - These helper functions were borrowed and modifed from

//     Dale Rogerson's book Inside COM.

 

// Set the given key and its value.

BOOL SetKeyAndValue(const TCHAR* pszPath,

                const TCHAR* szSubkey,

                const TCHAR* szValue) ;

 

// Convert a CLSID into a char string.

void CLSIDtoString(const CLSID& clsid,

               TCHAR* szCLSID,

               int length) ;

 

// Delete szKeyChild and all of its descendents.

LONG DeleteKey(HKEY hKeyParent, const TCHAR* szKeyString) ;

 

////////////////////////////////////////////////////////

//

// Constants

//

 

// Size of a CLSID as a string

const int CLSID_STRING_SIZE = 39 ;

 

/////////////////////////////////////////////////////////

//

// Public function implementation

//

 

//

// Register the component in the registry.

//

HRESULT RegisterServer(const CLSID& clsid,         // Class ID

                   const TCHAR *szFileName,     // DLL module handle

                   const TCHAR* szProgID,       //   IDs

                   const TCHAR* szDescription,  // Description String

                   const TCHAR* szVerIndProgID) // optional

 

{

   DT(szFileName);

   DT(szProgID);

   // Convert the CLSID into a char.

   TCHAR szCLSID[CLSID_STRING_SIZE] ;

   CLSIDtoString(clsid, szCLSID, sizeof(szCLSID)) ;

   //StringFromCLSID(clsid,szCLSID);

   // Build the key CLSID//{...}

   TCHAR szKey[64] ;

   lstrcpy(szKey, L"CLSID//") ;

   lstrcat(szKey, szCLSID) ;

   DT(szKey);

   // Add the CLSID to the registry.

   SetKeyAndValue(szKey, NULL, szDescription) ;

 

   // Add the server filename subkey under the CLSID key.

   SetKeyAndValue(szKey, L"InprocServer32", szFileName) ;

 

   // Add the ProgID subkey under the CLSID key.

   if (szProgID != NULL) {

      SetKeyAndValue(szKey, L"ProgID", szProgID) ;

      SetKeyAndValue(szProgID, L"CLSID", szCLSID) ;

   }

 

   if (szVerIndProgID) {

      // Add the version-independent ProgID subkey under CLSID key.

      SetKeyAndValue(szKey, L"VersionIndependentProgID",

         szVerIndProgID) ;

 

      // Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.

      SetKeyAndValue(szVerIndProgID, NULL, szDescription) ;

      SetKeyAndValue(szVerIndProgID, L"CLSID", szCLSID) ;

      SetKeyAndValue(szVerIndProgID, L"CurVer", szProgID) ;

 

      // Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.

      SetKeyAndValue(szProgID, NULL, szDescription) ;

      SetKeyAndValue(szProgID, L"CLSID", szCLSID) ;

   }

 

   return S_OK ;

}

 

//

// Remove the component from the registry.

//

HRESULT UnregisterServer(const CLSID& clsid,      // Class ID

                    const TCHAR* szProgID,       //   IDs

                    const TCHAR* szVerIndProgID) // Programmatic

{

   // Convert the CLSID into a char.

   TCHAR szCLSID[CLSID_STRING_SIZE] ;

   CLSIDtoString(clsid, szCLSID, sizeof(szCLSID)) ;

   //StringFromCLSID(clsid,szCLSID);

   // Build the key CLSID//{...}

   TCHAR szKey[64] ;

   lstrcpy(szKey, L"CLSID//") ;

   lstrcat(szKey, szCLSID) ;

 

   // Delete the CLSID Key - CLSID/{...}

   LONG lResult = DeleteKey(HKEY_CLASSES_ROOT, szKey) ;

 

   // Delete the version-independent ProgID Key.

   if (szVerIndProgID != NULL)

      lResult = DeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID) ;

 

   // Delete the ProgID key.

   if (szProgID != NULL)

      lResult = DeleteKey(HKEY_CLASSES_ROOT, szProgID) ;

 

   return S_OK ;

}

 

///////////////////////////////////////////////////////////

//

// Internal helper functions

//

 

// Convert a CLSID to a char string.

void CLSIDtoString(const CLSID& clsid,

               TCHAR* szCLSID,

               int length)

{

   assert(length >= CLSID_STRING_SIZE) ;

   // Get CLSID

   LPOLESTR wszCLSID = NULL ;

   HRESULT hr = StringFromCLSID(clsid, &wszCLSID) ;

   assert(SUCCEEDED(hr)) ;

   lstrcpy(szCLSID,wszCLSID);

   DT(szCLSID);

 

   // Free memory.

   CoTaskMemFree(wszCLSID) ;

}

 

//

// Delete a key and all of its descendents.

//

LONG DeleteKey(HKEY hKeyParent,           // Parent of key to delete

            const TCHAR* lpszKeyChild)  // Key to delete

{

   // Open the child.

   HKEY hKeyChild ;

   LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyChild, 0,

      KEY_ALL_ACCESS, &hKeyChild) ;

   if (lRes != ERROR_SUCCESS)

   {

      return lRes ;

   }

 

   // Enumerate all of the decendents of this child.

   FILETIME time ;

   TCHAR szBuffer[256] ;

   DWORD dwSize = 256 ;

   while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL,

      NULL, NULL, &time) == S_OK)

   {

      // Delete the decendents of this child.

      lRes = DeleteKey(hKeyChild, szBuffer) ;

      if (lRes != ERROR_SUCCESS)

      {

         // Cleanup before exiting.

         RegCloseKey(hKeyChild) ;

         return lRes;

      }

      dwSize = 256 ;

   }

 

   // Close the child.

   RegCloseKey(hKeyChild) ;

 

   // Delete this child.

   return RegDeleteKey(hKeyParent, lpszKeyChild) ;

}

 

// Create a key and set its value.

//

BOOL SetKeyAndValue(const TCHAR* szKey,

                const TCHAR* szSubkey,

                const TCHAR* szValue)

{

   HKEY hKey;

   TCHAR szKeyBuf[1024] ;

 

   // Copy keyname into buffer.

   lstrcpy(szKeyBuf, szKey) ;

 

   // Add subkey name to buffer.

   if (szSubkey != NULL)

   {

      lstrcat(szKeyBuf, L"//") ;

      lstrcat(szKeyBuf, szSubkey ) ;

   }

 

   // Create and open key and subkey.

   long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT ,

      szKeyBuf,

      0, NULL, REG_OPTION_NON_VOLATILE,

      KEY_ALL_ACCESS, NULL,

      &hKey, NULL) ;

   if (lResult != ERROR_SUCCESS)

   {

      DT(L"SetKeyAndValue Failed!");

      return FALSE ;

   }

 

   // Set the Value.

   if (szValue != NULL)

   {

      RegSetValueEx(hKey, NULL, 0, REG_SZ,

         (BYTE *)szValue,

         2*lstrlen(szValue)+1) ;

   }

 

   RegCloseKey(hKey) ;

   DT(L"SetKeyAndValue Succeed!");

   return TRUE ;

}

 

 

 

//componet.com

 

 

#include "stdafx.h"

 

 

#include "Registry.h"

//#include "ComTest.h"

#ifdef _MANAGED

#pragma managed(push, off)

#endif

HMODULE g_hModule = NULL;

ULONG    g_LockNumber = 0;

 

 

 

EXTERN_C const CLSID CLSID_TestObject;

EXTERN_C const CLSID IID_ObjectInterface;

//class CTestObjectFactory;

#include "TestObjectFactory.h"

STDAPI DllGetClassObject(const CLSID& clsid, const IID& iid, void **ppv)

{

   DT(L"DllGetClassObject...");

   if (clsid == CLSID_TestObject ) {

 

      CTestObjectFactory *pFactory = new CTestObjectFactory;

 

      if (pFactory == NULL) {

         return E_OUTOFMEMORY ;

      }

 

      HRESULT result = pFactory->QueryInterface(iid, ppv);

 

      return result;

   } else {

      return CLASS_E_CLASSNOTAVAILABLE;

   }

}

 

STDAPI DllCanUnloadNow(void)

{

   if (g_LockNumber == 0)

      return S_OK;

   else

      return S_FALSE;

}

STDAPI DllRegisterServer()

{

   TCHAR szFileName[MAX_PATH];

   ::GetModuleFileName((HMODULE)g_hModule,szFileName,sizeof(szFileName));

   DT(szFileName);

   return RegisterServer(CLSID_TestObject,szFileName,L"TestCom.Object",L"Test Componet",NULL);

 

}

 

 

 

STDAPI DllUnregisterServer()

{

   //return AMovieDllRegisterServer2(FALSE);

   return UnregisterServer(CLSID_TestObject,L"TestCom.Object",NULL);

 

}

BOOL APIENTRY DllMain( HMODULE hModule,

                       DWORD  ul_reason_for_call,

                       LPVOID lpReserved

                 )

{

   if (!g_hModule)

   {

      g_hModule = hModule;

   }

    return TRUE;

}

 

#ifdef _MANAGED

#pragma managed(pop)

#endif

C++ “接口”与“实现”分离的两种方法 接口需求 在软件开发这个行业中,一个较大的软件项目,一般由几个小组共同开发完成,为了将小组之间的影响降低到最低,定义好接口势在必行,如若要求短时间开发完成,定义好接口更是如此。或者说你的客户要求为其提供实现某个功能的接口,然后再在这些接口的基础上进行二次开发,如何定义才能定义好的接口呢? 第一,接口名字和实际的功能相符合;第二、接口要对数据进行封装,不允许客户直接操作接口之下的数据,尤其是使用n... 阅读详情

相关推荐

C#的COM事件在C++和JAVA中触发和响应的实现

在C++中调用C#开发COM组件时,一般的接口调用都比较容易实现,但是对于COM组件中的事件,C++中要去响应却不好实现。因为C#中事件是采用委托机制,而C++中却没有委托的机制,这样就无法实现对应。那要怎么办呢? 在C++中虽然没有委托的类型来对应,不过C++却可以开发ATL组件,同时里面有用到事件的映射,那么我们是不是可以应用这种机制去实现呢?进过不断的查找资料和一番努力,总算是达成了目标,

学而时习之 3004

C++中COM组件的创建和调用

在C++中COM组件的创建和调用

qianniulaoren的博客 4387

COM技术初探

COM技术初探(一) 一、COM是一个更好的C++ 1、COM 是什么 Don Box 说"COM IS LOVE"。COM 的全称是 ComponentObject Model 组件对象模型。 2、从 C++ 到DLL 再到 COM 2.1 C++ 如某一软件厂商发布一个类库(CMath四则运算),此时类库的可执行代码将成为客户应用中不可分割的一部分。假设此类库

把握自己。 2743

vs、c++环境下开发使用com组件

COM组件是一组接口的集合,由Win32动态链接库(DLL)或可执行文件(EXE)的形式发布的可执行二进制代码组成。com是独立于语言的组件体系结构,可以用C++、Java和VB等任意一种语言编写com对象。COM组件的优点有:通过接口对功能分类;功能扩充,只需添加接口就行;可轻松实现进程间调用、分布式调用;具有封装、继承、多态的面向对象特征。COM是规范,以该规范实现的DLL可视为COM组件。

baidu_16370559的博客 6854

COM编程入门:从理论到实践,手把手教你创建COM组件

COM编程详解:组件对象模型理论与实践文章的代码demo,原文链接,https://zhengjunxue.blog.youkuaiyun.com/article/details/152224401

c++开发一个简单累加的COM组件

1. COM组件的实现 2. COM组件的调用

C++和C#编写并且相互调用COM组件

<!-- alimama_pid="mm_10249644_1605763_4929893"; alimama_titlecolor="707070"; alimama_descolor ="CCCCCC"; alimama_bgcolor="FFFFFF"; alimama_bordercolor="FFFFFF"; alimama_linkcolor="DADA

3739

Ubuntu 20.04 server 安装

Ubuntu 20.04 server 安装 前面我们介绍了 Ubuntu Desktop 版本的安装,今天我们来看看 Ubuntu server 版本的安装。Ubuntu Server 版本的安装和 Desktop 有很大的区别,并且全程不能使用鼠标,只能通过键盘。 从光盘或 U 盘启动到 Welcome 界面,选择语言,一般都是使用 English,所以保保持默认,直接按回车即可; 系统检测到了新的版本,问你是否是否更新,这里我们不需要安装新的版本,所以选项 Continue without upda

as900的博客 1万+

C++调用C# com组件:一个完整的的小例子

    我们知道C#开发效率是非常高的,特别是做一些漂亮的页面就更适合用它了啊.如果你开发一个桌面应用程序即想性能好点又想页面漂亮点可以考虑用C++和C#一起用.反正现在Win7都集成NetFramework了,就不用纠结为了装个C#的应用程序而去再整个NetFramework装上.可以用C#做成com组件,然后C++去调用.反过来也行.可以C++做成com,然后C#来调用. 下面我举个简单的小...

weiwenhp 1万+

Mike 21如何制作随水深变化的糙率文件

MIKE 21如何制作随水深变化的糙率文件

zhuzhujiayoua的博客 2250

VirtualBox增强功能安装全指南:从下载到配置复制粘贴功能

本文详细介绍了VirtualBox增强功能的完整安装与配置流程,重点解决了虚拟机与主机间复制粘贴、文件拖放等核心协作难题。通过分步指南和故障排查,帮助用户在不同操作系统(如Windows、Linux)中实现无缝集成,提升虚拟化工作效率与体验。

weixin_29206669的博客 419

一个完整的COM 示例Demo(C++语言描述)

对于初学com的,一个完整的示例还是挺麻烦的,最近笔者也在学习,通过自己的摸索了解了下基本原理。在此将一个简单string的示例一步一步的详解。      源代码下载 1.创建工程 首先使用vs2010(笔者使用的vs2010就拿此来讲)创建一个工程。选择空项目,笔者命名为MyCom。 2.创建接口类 #ifndef IString_h__ #define

人生代码,代码人生。。。 1984

抖音小游戏(IAA)巨量引擎投放指南

摘要:本文详细介绍了在巨量引擎平台投放小游戏广告的完整流程,包括五个关键步骤:1)添加小游戏资产,填写ID等信息并等待审核;2)添加事件管理,配置激活和关键行为事件;3)通过橙子建站创建落地页,设置跳转链接;4)新建广告项目,选择小程序推广目标;5)完成广告创建。

分享前端工程化、AI 应用、Agent 开发与大模型实践! 4489

C++调用C#编写的COM组件

??????C++??????????C#???????C#?DLLC++????????????????????C#??COM???C++??? ??????????????? ????????????????????????????? ???VS2010 ???win764 32 ????C#??COM?? ????????????   ??   ??

MR_Sjx的博客 1637

YOLOv8+BiFPN双向特征金字塔:多尺度目标检测精度提升28%的实战教程

双向特征金字塔网络(BiFPN)是一种强化多尺度特征融合支持“自顶向下+自底向上”的双向特征流动,同时保留不同尺度的细节信息;引入加权融合机制,自动学习不同特征的重要性权重;裁剪冗余节点,在轻量化的同时提升融合效率。

m0_64661770的博客 492

PCL 模型滤波器【2025最新版】

根据给定的模型系数在点云中提取对应于模型的点云数据。博客长期更新,本文最新更新时间为:2025年6月17日。

点云侠的博客 4384

聊一聊被 .NET程序员 遗忘的 COM 组件

一:背景 1.讲故事最近遇到了好几起和 COM 相关的Dump,由于对 COM 整体运作不是很了解,所以分析此类dump还是比较头疼的,比如下面这个经典的 COM 调用栈。0:044>~~[138c]s win32u!NtUserMessageCall+0x14: 00007ffc`5c891184c3ret 0:061>k #Child-SP...

farway000的博客 219

头歌OpenGauss数据库-G.视图的使用

OpenGauss数据库-G.视图的使用

python一生之敌的博客 1384

[com]使用VS2022创建一个自定义com组件--C++

新手入门,不依赖atl创建com组件

南山cyd 4368

晶体管-二极管三极管MOS管选型参数总结

二极管三极管和MOS管,是电路中常用的控制电流电压的基本电子元器件。电路世界中晶体管的选型,需要考虑的参数多种多样,这些参数的选择会直接影响到电路的性能、稳定性、成本等多个方面。本文对二极管三极管和MOS管的选型参数进行详细介绍并总结。

fydar的博客 884

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

用纯粹的C++编写COM组件

赵湘宁下载本文代码    本文提供一个完全用C++实现的进程内(DLL)COM服务器,不要ATL或MFC提供任何支持。用这种方式编写COM对象可以让你深入地洞察到COM处理进程内服务器的方法以及COM是如何创建类工厂的。利用本文提供的这个简单框架你可以实现很基本的COM组件,如外壳扩展(Shell Extensions)等。如果你在使用过程中发现了任何问题,请将它反馈到vckbase@publ

.NET博文收藏 305

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

在Linux下实现COM组件(原创)

<br />好久没有写代码啦,今天翻到大学时候写的COM组件,当时那个叫崇拜COM技术啊。不过发现,工作中根本没啥用处。反正没事干,想想把COM组件在Linux环境下,实现一下。<br />COM组件是一种编程规范,它规定了软件编程的一般方法,虽然它由Microsoft公司制定和提出,但是它的规则也可以在Linux下使用,下面是在Linux下实现COM组件的方法。<br />----参考《COM技术内幕》一书。<br />COM实现的技术,主要是C++的虚函数、多继承以及动态链接库(DLL)技术。<br /

chenspnjupt1234的专栏 5815

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

C/C++ 实现COM转换到接口

在C++中可以使用类的方式来定义COM(Component Object Model)对象,并且一个COM对象可以实现多个接口。通过以上步骤,可以在C++中定义一个COM对象,并实现多个接口。这样,在其他应用程序中可以通过COM接口调用对象的方法,实现组件间的交互和互操作性。在COM对象的类中,实现每个接口所定义的方法。在方法的实现中,根据接口的要求提供相应的功能。为每个要实现的接口创建一个独立的COM接口。一个特殊的接口,所有COM接口都继承IUnKnown这个接口。接口,并且定义了接口所需的方法。

微软技术分享 1万+

C++开发一个简单累加的COM组件

C++开发一个简单累加的COM组件 去发现同类优质开源项目:https://gitcode.com/ 介绍 此仓库提供了一个使用C++开发的简单累加COM组件示例。本资源包含两个主要部分:COM组件的实现与COM组件的调用方法。 内容概览 COM组件的实现:详细介绍如何使用C++来创建一个COM组件,该组件提供累加功能。 COM组件的调用:展示如何在应用程序中调用该COM组件,实现数值的累加操作...

gitblog_06703的博客 768

【必修】软件复用与组件技术 学习笔记(二) chapter2 COM、接口

【必修】软件复用与组件技术 学习笔记(二) chapter2 COM、接口

Cambridge26的博客 623

[C#]C++调用dotNet组件的步骤

郑昀记录 200409C#写的组件,一般C++无法调用。除非在C#中这么做:第一步,修改HTMLParser工程属性:Build信息页中“Register for COM interop”设置为True。 第二步,在class特意声明:namespace HTMLParser{    [Guid("1F6EBDEF-1111-2222-86F2-0CEF0ED302E0")]    [Interf

软件开发资料汇总 522
上一篇: 如何从c++中调用c#的com组件
下一篇: 结构化异常处理和C++的异常处理区别
sheltonwan
博客等级 码龄20年 77粉丝 79原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值