COM技术内幕学习心得

PostgreSQL的学习心得和知识总结(三十二)|PostgreSQL数据库初始化阶段默认加载创建插件 目录结构 注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下: 1、参考书籍:《PostgreSQL数据库内核分析》 2、参考书籍:《数据库事务处理的艺术:事务管理与并发控制》 3、PostgreSQL数据库仓库链接,点击前往 4、参考书籍:《PostgreSQL中文手册》 1、本文内容全部来源于开源社区 GitHub和以上博主的贡献,本文也免费开源(可能会存在问题,评论区等待大佬们的指正) 2、本文目的:开源共享 抛砖引玉 一起学习 3、本文不提供任何资源 不存在任何交易 与任何组织和. 阅读详情

1: COM 技术内幕学习笔记

COM 基础实现方式( 方式 1 ) - 第一、二章

使用 CreateInstance 及 QueryInterface 实现的 COM

(方式 2 ) - 第三章

加入引用计数 ( 方式三 ) - 第四章

#include "stdafx.h"

#include "iostream.h"

 

#include <objbase.h>

 

interface IX

{

       virtual void FX1()=0;

};

 

interface IY

{

       virtual void FY1()=0;

};

 

class CA : public IX, public IY

{

public:

       BOOL _QueryInterface(const ID, void **pV);

 

    virtual void FX1()

       {

              cout<<"FX1()"<<endl;

       }

      

       virtual void FY1()

       {

              cout<<"FY1()"<<endl;

       }

 

};

 

int main(int argc, char* argv[])

{

       CA *pA = new CA();

   

       IX *pX = pA;

    pX->FX1();

 

       IY *pY = pA;

    pY->FY1();

 

       delete pA;

   

       return 0;

}

#include "stdafx.h"

#include "iostream.h"

 

#include <objbase.h>

 

class CUnknown

{

public:

       virtual BOOL _QueryInterface(const ID, void **pV) = 0;

};

 

class IX : public CUnknown

{

public:

       virtual void FX1()=0;

};

 

class IY : public CUnknown

{

public:

       virtual void FY1()=0;

};

 

class CA : public IX, public IY

{

public:

       BOOL _QueryInterface(const ID, void **pV);

 

    virtual void FX1()

       {

              cout<<"FX1()"<<endl;

       }

      

       virtual void FY1()

       {

              cout<<"FY1()"<<endl;

       }

 

};

 

enum {IID_IX, IID_IY};

BOOL CA::_QueryInterface(const ID, void **pV)

{

       if (ID == IID_IX)

       {

              *pV = static_cast<IX *>(this);

             

              return TRUE;

       }

       else if (ID == IID_IY)

       {

              *pV = static_cast<IY *>(this);

             

              return TRUE;

       }

 

       return FALSE;

}

 

CUnknown* CreateInstance()

{

       CUnknown *pI = static_cast<IX *>(new CA());

      

       return pI;

}

 

int main(int argc, char* argv[])

{

       CUnknown *pUnknown = CreateInstance();

   

       IX *pX = NULL;

       pUnknown->_QueryInterface(IID_IX, (void **)&pX);

       pX->FX1();

 

    IY *pY = NULL;

    pX->_QueryInterface(IID_IY, (void **)&pY);

    pY->FY1();

 

       delete pUnknown;

 

       return 0;

}

#include "stdafx.h"

#include "iostream.h"

 

#include <objbase.h>

 

class CUnknown

{

public:

       virtual BOOL _QueryInterface(const ID, void **pV) = 0;

       virtual void _AddRef() = 0;

       virtual void _Release() = 0;

};

 

class IX : public CUnknown

{

public:

       virtual void FX1()=0;

};

 

class IY : public CUnknown

{

public:

       virtual void FY1()=0;

};

 

class CA : public IX, public IY

{

public:

       CA();

       virtual ~CA();

 

public:

       virtual BOOL _QueryInterface(const ID, void **pV);

       virtual void _AddRef();

       virtual void _Release();

 

    virtual void FX1()

       {

              cout<<"FX1()"<<endl;

       }

      

       virtual void FY1()

       {

              cout<<"FY1()"<<endl;

       }

 

private:  

       int m_nRef;

};

 

enum {IID_IX, IID_IY};

BOOL CA::_QueryInterface(const ID, void **pV)

{

       BOOL bReturn = FALSE;

      

       if (ID == IID_IX)

       {

              *pV = static_cast<IX *>(this);

              bReturn = TRUE;

       }

       else if (ID == IID_IY)

       {

              *pV = static_cast<IY *>(this);

              bReturn = TRUE;

       }

    if (*pV != NULL)

          static_cast<CUnknown *>(*pV)->_AddRef();

      

       return (bReturn) ? TRUE : FALSE;

}

 

void CA::_AddRef()

{

       ++m_nRef;

}

 

void CA::_Release()

{

       if (--m_nRef == 0)

       {

              delete this;

       }

}

 

CA::CA()

{

       m_nRef = 0;

}

 

CA::~CA()

{

}

 

CUnknown* CreateInstance()

{

       CUnknown *pI = static_cast<IX *>(new CA);

       pI->_AddRef();

 

       return pI;

}

 

int main(int argc, char* argv[])

{

       CUnknown *pUnknown = CreateInstance();

   

       IX *pX = NULL;

       pUnknown->_QueryInterface(IID_IX, (void **)&pX);

       pX->FX1();

       pX->_Release();

 

       IY *pY = NULL;

    pX->_QueryInterface(IID_IY, (void **)&pY);

    pY->FY1();

       pY->_Release();

   

       pUnknown->_Release();

 

       return 0;

}

结论:

    1 : COM 接口在 c++ 中是用纯抽象基类来实现的

2 :一个 COM 组件可以提供多个接口

3 : C+ +类通过多重继承来实现提供多接口组件

 

不足之处:

1 :客户,组件之间通过接口通信来实现没有突出。

2 :客户端要使用到组件的声明( new CA() )

结论:

    1 :通过使用 CreateInstance 来摆脱组件类声明

       ( 使用不再使用指向 CA 的指针 )

2 :可以看出客户,组件通过接口通信的锥形

 

不足之处:

1 :没有添加引用计数及释放引用计数

结论 : ( 在方式二的基础上 )

    1: 通过使用引用计数来完成删除组件方法

 

动态连接 ( 方式四 ) – 第五章

 

Client program

// CallCreate.cpp : Defines the entry point for the console application.

//

 

#include "stdafx.h"

 

/* reference to the dll head file and copy from .dll file into the client program

   under file that cann't be found by it

//*/

#include "../Create/cmpnt1.h"

 

CUnknown* CallInstance(char *name);

 

typedef CUnknown* (*PCREATEINSTANCE)();

 

CUnknown* CallInstance(char *name)

{

    HINSTANCE hInst = ::LoadLibrary(name);

       if (hInst == NULL)

       {

              cout<<"fail to loadLibrary"<<endl;

              return NULL;

       }

      

       PCREATEINSTANCE pCreateInstance = (PCREATEINSTANCE)::GetProcAddress(hInst, "CreateInstance");

       if (pCreateInstance == NULL)

       {

              cout<<"cann't find the function"<<endl;

              return NULL;

       }

 

       return pCreateInstance();

}

 

int main(int argc, char* argv[])

{

       CUnknown *pUnknown = CallInstance("Create.dll");

 

       IX *pX = NULL;

       pUnknown->_QueryInterface(IID_IX, (void **)&pX);

       pX->FX1();

       pX->_Release();

 

       IY *pY = NULL;

    pX->_QueryInterface(IID_IY, (void **)&pY);

    pY->FY1();

       pY->_Release();

   

       pUnknown->_Release();

 

       return 0;

}

 

 

 

 

 

Dll

// #head file cmpnt1.h 

#define DLL_CREATE_INSTANCE  extern "C" __declspec(dllexport)

#include "cmpnt1.h"

 

BOOL CA::_QueryInterface(const ID, void **pV)

{

       BOOL bReturn = FALSE;

      

       if (ID == IID_IX)

       {

              *pV = static_cast<IX *>(this);

              bReturn = TRUE;

       }

       else if (ID == IID_IY)

       {

              *pV = static_cast<IY *>(this);

              bReturn = TRUE;

       }

    if (*pV != NULL)

          static_cast<CUnknown *>(*pV)->_AddRef();

      

       return (bReturn) ? TRUE : FALSE;

}

 

void CA::_AddRef()

{

       ++m_nRef;

}

 

void CA::_Release()

{

       if (--m_nRef == 0)

       {

              delete this;

       }

}

 

CA::CA()

{

       m_nRef = 0;

}

 

CA::~CA()

{

}

 

CUnknown* CreateInstance()

{

       CUnknown *pI = (CUnknown*)(void*)new CA();

       pI->_AddRef();

       return pI;

}

 

#implement file(cmpnt.h)

#ifndef CMPNT1_H

#define CMPNT1_H

 

#ifdef DLL_CREATE_INSTANCE

 

#else

   #define DLL_CREATE_INSTANCE extern "C" __declspec(dllimport)

#endif

  

#include <windows.h>

#include "iostream.h"

#include <objbase.h>

 

class CUnknown;

DLL_CREATE_INSTANCE CUnknown* CreateInstance();

enum {IID_IX, IID_IY};

 

class CUnknown

{

public:

       virtual BOOL _QueryInterface(const ID, void **pV) = 0;

       virtual void _AddRef() = 0;

       virtual void _Release() = 0;

};

 

class IX : public CUnknown

{

public:

       virtual void FX1()=0;

};

 

class IY : public CUnknown

{

public:

       virtual void FY1()=0;

};

 

class CA : public IX, public IY

{

public:

       CA();

       virtual ~CA();

 

public:

       virtual BOOL _QueryInterface(const ID, void **pV);

       virtual void _AddRef();

       virtual void _Release();

 

    virtual void FX1()

       {

              cout<<"FX1()"<<endl;

       }

      

       virtual void FY1()

       {

              cout<<"FY1()"<<endl;

       }

 

private:  

       int m_nRef;

};

#endif //CMPNT1_H

 

结论:

     由于组件中客户所需要的所有函数都可以通过一个接口指针而访问到,因此需要      

在 DLL 中输出 CreateInstance() 函数以便客户调用它。

不足之处:

      客户和组件之间还是存在一种紧密的连接,客户必须要知道实现组件的 DLL 名称。

 

   

 

第六章主要介绍如何通过CLSID 来查找相应DLL 名字的方法, 避免了客户通过DLL 文件名来锁定组件的依赖(第五章没有解决的问题) 。 由于安装程序及REGSVR32.EXE 可以调用实现组件的DLL 中输出的DllRegisterServer 函数来注册相应的组件,注册时相应的CLSID 和DLL 文件名也记录到注册表中,window 通过查找HKEY_CLASSES_ROOT 根目录下的CLSID 关键字,查找其下面的InproServer32( 进程中服务器,DLL 就是) ,在这个关键字里面记录了DLL 文件的名字。

第七章总结: ( 本章主要讲述类厂 )

1: 几个重要的函数及其内部关系 CoCreateInstance , CoGetClassObject

STDAPI CoCreateInstance(

  REFCLSID rclsid ,     //Class identifier (CLSID) of the object

  LPUNKNOWN pUnkOuter , // 表明创建的组件是否为聚合 (具体第八章进行讨论)

  DWORD dwClsContext ,  // 表明组件,客户是否在不同的上下文进行工作(进程中,本地,远程) (具体第十章进行讨论)

  REFIID riid ,         //Reference to the identifier of the interface

  LPVOID * ppv          //Address of output variable that receives

                        // the interface pointer requested in riid

);

STDAPI CoGetClassObject(

  REFCLSID rclsid ,  //CLSID associated with the class object

  DWORD dwClsContext , //Context for running executable code

  COSERVERINFO * pServerInfo , // 用于控制对远程组件的访问 (具体第十章进行讨论) Pointer to machine on which the object is to  be instantiated

  REFIID riid ,      //Reference to the identifier of the interface

  LPVOID * ppv       //Address of output variable that receives the

                      // interface pointer requested in riid

);

就像我们在第五章看到的一样: CallCreateInstance 调用 Dll 中 CreateInstancee 来创建所需组件, CoGetClassObject ( COM 库) 需要 DLL 中一个特定的函数来 创建组件的类厂 。此函数就是 DllGetClassObject ( DLL )-可以在同一个 DLL 中实现多个组件 ( 第九章:可复用的类厂 )

STDAPI DllGetClassObject(

  REFCLSID rclsid ,  //CLSID for the class object

  REFIID riid ,      //Reference to the identifier of the interface

                     // that communicates with the class object

  LPVOID * ppv       //Address of output variable that receives the

                     // interface pointer requested in riid

);

某个组件的类厂一般而言都将实现 IclassFactory 接口,但也有特别的如 IclassFactory2.

HRESULT CreateInstance(

  IUnknown * pUnkOuter ,  // 表明创建的组件是否为聚合 , 该参数是由 CoCreateInstance 来传递的 (具体第八章进行讨论) Pointer to whether object is or isn't part of an aggregate

  REFIID riid ,           //Reference to the identifier of the interface

  void ** ppvObject       //Address of output variable that receives the

                          // interface pointer requested in riid

);

以上这些函数在客户, COM 库, DLL, 类厂,组件 之间的调用关系

  DllGetClassObject 实现的是 factory 组件,

  IClassFactory::CreateInstance() 实现的是 CA 组件

 

组件的注册:

  实现组件注册需要在 DLL 文件中输出四个如下文件:

DllRegisterServer, DllUnRegisterServer,DllGetClassObject,

· DllRegisterServe r 、 DllUnRegisterServer :作用是在 windows 的注册表中登记或取消某个组 件登记— 需要包含 DLL 文件的模块句柄 ( 通过 DllMain 传递 ) ,以获取 DLL 的文件名登记或取消它。

· DllGetClassObject 作用是用于 COM 库创建类厂

· DllCanUnloadNow() : 由 COM 库调用来检查是否服务器被从内存中卸载 。

 

定义在 .def 文件中

EXPORTS

    DllRegisterServer   PRIVATE

    DllUnregisterServer PRIVATE

    DllGetClassObject   PRIVATE

DllCanUnloadNow     PRIVATE

每一行都包含函数名和 PRIVATE 关键字。这个关键字的意思是:此函数是输出函数,但不包含在输入库( import lib )中。也就是说客户端不能直接从代码中调用这个函数,即使是链接了输入库也不行。这个关键字时必须要用的,否则链接器会出错。
因为 STDAPI 的扩展。输出必须使用 .DEF 文件

                                                                                   

第八章 主要介绍内容:

为什么组件变化对客户无影响:

   原因是: COM 支持接口继承而不支持实现继承 ;这也就是 基于抽象基类构建应用程序 而不用担心基类有时发生变化造成派生类不能正常使用的好处。

   包容作用:

   由于 COM 没有实现继承,所以使用 组件包容来完全模拟实现继承 。

   包容特点:

   1 :外部组件是内部组件的客户。

   2 :外部组件使用内部组件接口来完成自己接口的实现

   3 : 释放: 在将外部组件释放之前先将内部组件进行释放。

 

接口是基于组件的: 要想获得接口,首先要考虑到如何创建组件。

包容与聚合是 COM 用以实现组件复用的技术或者说是一种机制,它们类似于继承。

当一个组件 ( 外部组件 ) 包容另一个组件 ( 内部组件 ) 时,外部组件包含一个内部组件接口的指针,并重新实现此接口供其客户调用。在重新实现的这个接口中,外部组件只是简单的将调用请求转发给内部组件。包容的实现比较简单,

当外部组件聚合内部组件时,外部组件没有重新实现内部组件的接口和进行调用转发,而是把内部组件接口的指针直接返回给客户,从而使客户能够直接与内部组件打交道。但是,必须保证客户不能访问内部组件的 IUnknown 接口,不能也没有必要让客户知道它正在与另一个组件 -- 即所谓的内部组件交互,否则一切将变得十分混乱

 

包容实现的主要思想 :

     组件 CA(funA, funB) 包含了组件 CB.(funB)

     Virtual void CA::funB()

     {

… .

          m_pB->funB();

… .

     }

 

创建 CA 的时候 , 在 CA::CreateInstance 的时候再创建 CB(). 同事获得 m_pB 接口

CA::CreateInstance

{

     Init()

}

CA::Init()

{

   CoCreateInstance(COMPLENT_2, … , m_pB)

}

 

聚合实现的主要思想 ( 被聚合的组建要完成实现两个接口 , 一个是 IUnknown 接口 , 另一个是实现 INondelegatingUnknown 接口 )

 

聚合实现的重要过程及其原理 :

为了实现组件 A 聚合组件 B 的某个接口 ISomeInterface ;对 A 初始化的时候,创建内部组件 B ,并把 A 的 this 指针传给 B ,内部组件返回   INondelegatingUnknown 接口并传给 A 的成员变量 m_pUnknownInner ,最后在 A 中查询 ISomeInterface 时,使用了 m_pUnknownInner->QueryInterface(...) ;可是 INondelegatingUnknown 的定义中没有 QueryInterface 啊,只有 NondelegatingQueryInterface 。   这是为什么?

其实组件之间是靠vtable  来通信的的 ,而不是C++ 的类定义, 他会去调用 NondelegatingQueryInterface 方法.

 

第九章 主要介绍内容:

Q: 把 IY 接口指针赋值给 IZ, 结果会怎样呢 .

IZ *pIZ;

pIX->QueryInterface( IID_IY , (void **)& pIZ );

A: 两种方法可以解决 ( 其一智能指针来封装接口指针 , 其二通过包装类来对接口进行封装 )

智能指针来封装接口指针 :

通过包装类来对接口进行封装 :

 

 

接地设计的本质:按电流类型选择物理连接方式 接地是电子系统中实现电位参考、噪声抑制与安全保护的基础技术,其核心原理在于为不同性质的电流提供可控的低阻抗返回路径。从直流到GHz频段,电流的频率特性、能量等级和持续时间决定了接地的物理实现方式——工频安全电流依赖低电阻导体,高频噪声需低感平面或磁珠衰减,ESD脉冲要求受控泄放电阻,浪涌能量则必须通过独立短路径导入大地。这种‘目的决定方式’的设计逻辑,直接关联EMC合规性、信号完整性与系统可靠性。本文聚焦PCB级与设备级工程实践,详解安全地、功能地、浪涌地与静电地的判据差异及六种典型连接策略,帮助硬件工程师 阅读详情

相关推荐

若依Vue整合积木报表实战:Token安全校验全流程解析

本文详细解析了在若依Vue后台系统中安全集成积木报表的全流程,重点阐述了Token安全校验的核心机制。通过前端菜单配置、Token传递、后端权限拦截及自定义Token服务实现,构建了一套完整的企业级报表访问安全防线,确保核心业务数据的安全可控。

t8u9v0的博客 578

CoCreateInstance调用COM接口伪流程

在编写组件程序时,经常会使用CoCreateInstance直接取COM组件的接口,非常方便,那CoCreateInstance到底干了些什么事呢?1、CoCreateInstance取COM组件的接口的基本流程 //参数:rclsid = 组件CLSID //参数:riid = 接口ID WINOLEAPI CoCreateInstance(REFCLSID rclsid, L...

weixin_30555125的博客 384

当Flowable遇上AI:智能流程决策的未来探索

本文探讨了Flowable工作流引擎与AI技术的融合,构建智能流程决策系统的前沿实践。通过动态流程控制、机器学习优化表达式、自然语言生成规则等创新方法,显著提升业务流程的自动化水平和决策效率。重点解析了AI如何赋能Flowable核心引擎,实现从静态规则到动态智能的跨越式发展。

weixin_29271053的博客 392

COM类厂及CoCreateInstance

CoCreateInstanceCom库中包含一个创建组件的名为CoCreateInstance的函数。声明是:HRESULT _stdcall CoCreateInstance(      Const CLSID& clsid,      IUnknown* pIUnknown

xust999的专栏 2296

PCB设计实践(三十二)PCB设计遇到大电流时的设计技巧

本文系统阐述10A至数百安培PCB设计的六大关键技术。载流能力优化强调铜厚选择(2-4oz)、线宽计算及并联结构;热管理提出散热孔阵列、铜基板嵌入等方案;布局策略包括功率分区和低阻抗路径设计;材料工艺推荐铝基板、陶瓷基板等高效解决方案;安全设计涵盖电气隔离与保护电路;验证环节需结合热仿真与实测。典型150A电机驱动板案例显示,通过4oz铝基板、散热孔阵列等设计,可实现温升≤45℃的稳定运行。核心在于铜厚线宽协同、主动散热及严格验证。

致力于硬件设计、人工智能知识及技术的分享,不断鞭策自己成长,共同进步! 4230

Python量化入门:用pytdx获取800个交易日K线数据的完整指南(附代码)

本文为Python量化交易初学者提供了使用pytdx库免费获取股票日线级别K线数据的完整指南。文章详细介绍了从环境搭建、单只股票数据获取,到构建健壮的批量下载器、数据清洗与验证,再到基础分析与可视化的全流程,并附有可直接运行的代码示例,帮助读者快速建立本地股票数据库。

weixin_29050513的博客 1465

COM对象创建过程详细分析

1、   CoGetClassObject 函数原型: HRESULT CoGetClassObject(const CLSID& clsid, DWORD dwClsContext, COSERVERINFO* pServerInfo, const IID& iid, (void **)ppv); 参数说明:          clsid: 指定COM类厂的CLSID标识符;     

xiangzhang321的专栏 1317

黑客渗透测试后门隐藏技术揭秘

本文介绍了在授权渗透测试中隐藏后门文件(muma.exe)的多种技术手段。主要包括:通过WinRAR自解压脚本将后门与正常程序捆绑实现双开;利用系统自动运行目录和注册表实现开机自启;修改文件图标伪装成常用软件;将文件存放在冷门系统目录;设置系统+隐藏双重属性增强隐蔽性。此外还涉及对抗安全软件的加壳(UPX)、免杀(msfvenom编码)技术,以及进程注入、日志清除等运行隐藏方法。所有技术仅限合法授权测试使用,未经授权使用将面临法律责任。

m0_60781580的博客 1040

com的一般调用步聚

无论编写哪种类型的组件程序,最终目的都是为了服务于客户程序。客户程序对COM对象的调用通常是通过调用COM API函数来进行,最为核心的COM API函数是CoGetClassObject,下面是这个函数的原型。 HRESULT CoGetClassObject(REFCLSID rclsid, DWORD dwClsCtx, COSERVERINFO *pcsi, REFIID riid, vo...

weixin_30394333的博客 142

使用逻辑分析仪处理IIC信号

逻辑分析仪

xc_123的博客 4485

MCU启动流程详解

在MCU启动后,系统从flash主存储区开始执行,先将0x08000000地址存放的堆栈栈顶指针赋给SP寄存器,将0x08000004地址存放的Reset_Handler复位向量地址赋给PC寄存器跳转执行系统复位,期间执行System_Initializes函数配置系统时钟,重定位向量表,执行MDK自带库函数__main将RW、ZI数据段从Flash加载到RAM,并跳转至_rt_entry进行Stack和Heap的初始化,最后跳转到熟悉的main函数。

weixin_50827397的博客 1505

学习COM的过程

在八月份的时候遇到了《COM技术内幕》一书。经过几天耐心的阅读, 我发现了两个问题。一  第一次了解了COM并知道了它的基本原理。二   COM技术就是我一直想了解的东西。很快,我就能够自己编写第七章的例程。但在随后的数个月中(9月-至今)再也没有任何期望的理解上面的突破。

晓山科技的专栏 531

51单片机计算器(源程序+流程图+答辩报告+综合设计)

保姆级讲解!C语言编程,使用51单片机及LCD1602显示屏实现!

m0_57007304的博客 2万+

Com组件和DirectShow学习心得。。。。。。。。。

最近在看DirectShow,DirectShow又是基于COM的,因此这里来谈一谈COM,以笔记和心得的形式.后面会陆续更新包括DirectShow因为是心得和笔记,叙述和理解可能有错误(红色标记的我是不确定的理解),欢迎大家指正。。。。。  需要了解的名词在微软的COM中GUID和UUID、CLSID、IID都是同一个结构体的不同命令,所以各自代表的意义不同:UUID 

挨踢 1582

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

初学COM的感觉,分享

COM这个名词,我想大家都已熟悉,而且,我每一天的生活,可以说都在享受着它带给我们的无限便利。但是最近因为要做一个远程监控的模块,要用DirectShow,但是,大家知道,DIRECTX都是构建在COM基础之上的,DirectShow更是随处可见COM的影子,虽然,MSDN说学须要掌握太多的COM知识就可以进行开发,但是,我自己是一个因欢寻根的人,于是非要想把COM的机制搞清楚。可一旦开始之后,才...

weixin_30649641的博客 106

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

COM组件学习笔记一

困惑:         1、看了公司的代码,组件好复杂

xiaodeihong的专栏 663

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

自己的五年计划

做为刚刚进入初窥VC++门径的菜鸟来说,越来越感觉到现在的编程越来越不局限于工具的使用以及语言的使用,想当初delphi,c++bulider何其风光,可如今,已是昨日黄花。VC也号称强大,MFC式的编程一度成为主流,可如今隐隐有力不从心的感觉。这就是如今IT人的杯具,今天是这种语言流行,你就必须学这种语言,明天那种技术流行你就一定要学那种技术,不为别的,只为了混口饭吃,老板永远不关心用什么开发,

badbirdboy的专栏 909

java学习的二三事--给cims新人

最近有师弟师妹询问java学习路线相关的问题,就在这里作一个稍具体的回复,同时也正好对自己近来的一些经历、教训和感悟进行一个总结,希望对师弟师妹有所帮助,也希望自己能够不忘初心继续前行。先多嘴几条学习建议: 1.如果对于一块新的知识完全没有概念,那么可以先看教学视频(网上搜或者淘宝买,注意要挑选新的、内容全的),视频的好处是通俗易懂,有老师指点可以很快形成条理,明确重点,很适合新手;但是它的缺点是比

小菜鸟也想飞的博客 1246

一个学长度过的书

读书是扎实基础提升技能的一个有效途径之一,另外一个就是实战。当然最好能二者结合,否则都会有这种感觉,自己总是缺乏实战经验 亦或 自己基础不扎实。本人作为跨专业的,说实话没有搞过神马含金量很高的项目。一年多时间倒是读了不少书,以下书都是我看过超过一半的,当然有的书看过很多遍,有的书看了一遍就没再碰,供师弟师妹参考,书不能说都好,但都不算差:  以下为C/C++/STL基础: C程序设计语言 C

aci353的专栏 494

COM组件创建过程

COM组件的创建可以通过CoCreateInstance()函数来完成,函数原型为: HRESULT __stdcall CoCreateInstace(  const CLSID& clsid,  IUnknown* pIUnknownOuter,  DWORD dwClsContext,  const IID& iid,  void** ppv );

流浪的码农 3318

COM学习笔记(五):CoCreateInstance

在COM库中包含一个用于创建组件的名为CoCreateInstance的函数。此函数需要一个CLSID参数,创建相应组件的一个实例,并返回此组件的某个 接口。 COCreateInstance的声明: HRESULT __stdcall CoCreateInstance( const CLSID& clsid, IUnknown* pIUnknowOuter,//Outer COmpon

yangchuankai's blog 1688

(转载)超酷代码:来自 COM 经验的八个教训

超酷代码:来自 COM 经验的八个教训发布日期: 5/20/2004 | 更新日期: 5/20/2004Jeff Prosise在日常工作中,我看到过许多由不同开发人员编写的 COM 代码。我为许多富于创造性的使用 COM 的工作方式感到惊讶,有一些使 COM 工作的巧妙代码可能连 Microsoft 都没有想到。同样,看到一些错误一次又一次地重犯,使我免不了心灰意懒。这些错误很多

无限天空 1689

COM 学习笔记,2------引用计数,注册,类厂

  引用计数 AddRef 和 Release 函数 当客户从组 件取 得一 个接口 时 , 此引 用计 数值 将 增 1。 当 客户 使用 完某个接口后 , 组件的引用计数值将减 1。 当引用计数值 为 0 时 , 组件 即可将自 己从内存 中删除   三个简单的原则: 返回之前调用AddRef,对于那些返回接口指针的函数,在返回之前应用相应的指针调用AddRef 。这些函数包括Qu...

商少 934

泛读笔记-COM原理与应用---1

1.COM模型中,客户请求服务时,只能通过接口进行。 每个接口都由一个128位的全局唯一标识符(GUID)标识。 客户通过GUID获得接口的指针 通过接口指针,客户可调用相应的成员函数 客户用一个128位的GUID来标识对象,称为CLSID。 系统中有这类COM对象的信息,包括COM对象所在的模块文件,COM对象在代码中的入口点, 客户程序可由CLSID来创建COM对象。 客户创建对象后,得到的是...

x13262608581的博客 564

.Net下进程外COM服务器的实现

要求:为一个WinForm程序暴露一个COM接口,让其它应用程序能够以COM服务器(LocalServer)方式启动这个程序并且对其进行操作如果发现已经在运行的应用程序,则直接重用当前运行的应用程序进行操作。分析:根据要求,分解具体需要解决的技术问题如下:在WinForm程序中定义一个COM visible接口并实现。将这个Winform程序变为COM服务器(LocalServer)。将Win

633

COM学习笔记4_创建COM组件的实现

为了实现COM的动态链接,必须把组件的实现和客户代码分隔开。一种处理是把组件放入DLL中。这样为了支持客户创建组建,组件需要导出一个类似CreateInstance的函数。extern "C" IUnknown* CreateInstance(){ IUnknown* pI = static_cast(new CA) ; pI->AddRef() ; return pI

hongjiqin的专栏 2667
上一篇: 阅读windows核心编程有感
下一篇: 主动模式
testing2007
博客等级 码龄19年 46粉丝 59原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值