惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - abraham

I want learn the programming web by C#.Who can give a simple step by step tutorial,please? Today begin new life of blog. I want learn the programming web by C#.Who can give a simple step by step tutorial,please? Today begin new life of blog. create dll formt lib with cpp funcs or c just funcs by hand. pub class into dll in dos by hand step by step. put class into dll by using vc6.0 How To Read a Big Txt File into CEdit and write it as save!. Create a Dlg's Thread and use it,this can use dlg handle. Create a Thread and Use it. Here is a reason why can not log a SQL CString How to Kill Blanks in a CString,but how to kill Chinese Blanks i can not solve. How to get a Chinese character's PinYin automaticly? PE format is very important,so learn it. create a dll by hand. static/register/atuo/extern/volatile/const STL is very important,so we learn. print a bmp 2 - abraham Create COM step by step 2. - abraham
Create com step by step.1
abraham · 2004-03-31 · via 博客园 - abraham

目录:

介绍

接口

第一步:创建IDL文件

第二步:生成类型库

第三步:从IAdd继承

第四步:实现IAdd的方法

第五步:实现IUnkown

第六步:类工厂

第七步:实现IClassFactory的方法

第八步:实现DllGetClassObject

第九步:实现DllCanUnloadNow

第十步:DllRegisterServerUnregisterServer

第十一步:将IDL文件插入到工作空间中

第十二步:在Visual Basic 中使用COM刚创建的对象

 第十三步:分析我们刚创建的所有文件

第十四步:在ActiveX DLL中嵌入类型库

第十五步:从Visual C++客户方使用刚创建的COM对象

介绍

对于我来说,理解COM(Component Object Model)至少是不止一次的冒险旅行了。我相信,每一个希望理解COM背后基本理论的程序员,一定有过使用没有MFC/ATL的模板和宏帮助下的C++语言写了至少一个以上的简单的COM对象。在这篇文章中,我会根据COM的基本原理,介绍创建一个简单COM对象的步骤。这个创建的组件可以在VC/VB的客户端使用。

作为练习,我们会试图设计一个COM对象,实现一个假想的超级快速的加法算法。这个组件有两个长整型(long type)的参数,其返回值也是一个长整型数,是我们加法算法的结果。下面我们就开始设计这个接口。

接口

COM对象的接口,我们不会谈到实际的实现,而是要谈论使用这个COM对象并与之通信的方法签名(method signatures)。我们将会命名我们的接口为IAdd 这个接口的声明使用接口定义语言来完成(Interface Definition Language --IDL),接口定义语言是用来定义函数签名(Function Signatures)的,它使用一种独立于编程语言的格式,这有助于RPC组织从一个计算机到另一个的打包、分发和解包的参数。在我们的接口IAdd中,我们有两个方法SetFirstNumberSetSecondNumber,这两个方法用来传递加法使用的参数。然后,还有另外一个方法DoTheAddition,他用来计算实际的结果并将结果返回给客户。

第一步:创建IDL文件

创建一个新的win32 DLL工程(命名为AddObj)。接下来的所有文件将被创建到此文件夹。创建一个空文件并键入下面的内容,把它保存为IAdd.idl。接口标识符使用uuidgen.exe生成(uuidgen.exe是一个dos文件,可以在命令行直接运行它)

import "unknwn.idl";

[

object,

uuid(1221db62-f3d8-11d4-825d-00104b3646c0),

helpstring("interface  IAdd is used for implementing a super-fast addition Algorithm")

]

interface IAdd : IUnknown

    {

    HRESULT     SetFirstNumber(long nX1);

    HRESULT     SetSecondNumber(long nX2);

    HRESULT     DoTheAddition([out,retval] long *pBuffer);

    };

[

uuid(3ff1aab8-f3d8-11d4-825d-00104b3646c0),

helpstring("Interfaces for Code Guru algorithm implementations .")

]

library CodeGuruMathLib

    {

    importlib("stdole32.tlb");

    importlib("stdole2.tlb");

    interface IAdd;

    }

第二步 生成类型库

使用IDL编译器MIDL.EXE编译接口定义文件IAdd.idl。编译完成后,将会生成以下的文件:

IAdd.h

包含C++格式的接口声明

dlldata.c

包含代理DLL的代码。当在一个不同的处理器/计算机上调用对象时使用

IAdd.tlb

二进制文件。使用一个定义好的格式完全的描述我们的IAdd接口和它所有的方法。这个文件和COM组件分发给所有的客户。

IAdd_p.c

包含代理DLL的列集代码。当在一个不同的处理器/计算机上调用对象时使用

IAdd_i.c

包含接口IDIID

(译者注:编译方法为,如过你的机器已经安装了Visual Studio环境的话,那么你可以直接从命令行写入如下的语句,midl.exe ..\ AddObj\iadd.idl

第三步 IAdd继承

我们将在此步骤中创建一个COM对象。创建一个新文件(AddObj.h),声明一个C++类,命名这个类为CAddObj,从接口IAdd继承(在文件IAdd.h)。记住,IAdd继承自IUnknownIUnknown是一个抽象基类。因而我们不得不像IUnknown一样为抽象基类IAdd声明所有的方法。

#include    "IAdd.h"

extern long g_nComObjsInUse;

class CAddObj :

        public IAdd

    {

    public:

    HRESULT __stdcall QueryInterface(

                                REFIID riid ,

                                void **ppObj);

    ULONG   __stdcall AddRef();

    ULONG   __stdcall Release();

    HRESULT __stdcall SetFirstNumber( long nX1);

    HRESULT __stdcall SetSecondNumber( long nX2);

    HRESULT __stdcall DoTheAddition( long *pBuffer);

    private:

    long m_nX1 , m_nX2;

    long m_nRefCount;  

    };

 

第四步 实现IAdd的方法

我们将在此步骤中提供接口IAdd所有方法的实现。

创建一个新文件(AddObj.cpp),在此文件中添加如下实现代码。

#include    <objbase.h>

#include    "AddObj.h"

#include    "IAdd_i.c"

HRESULT __stdcall CAddObj::SetFirstNumber( long nX1)

    {

    m_nX1=nX1;

    if (m_bIsLogEnabled) WriteToLog("Junk");

    return S_OK;

    }

HRESULT __stdcall CAddObj::SetSecondNumber( long nX2)

    {

    m_nX2=nX2;

    return S_OK;

    }

HRESULT __stdcall CAddObj::DoTheAddition( long *pBuffer)

    {

    *pBuffer =m_nX1 + m_nX2;

    return S_OK;

    }

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

第五步 实现IUnknown

IUnknown方法需要被实现。在文件AddObj.cpp中,我们将实现它的三个强制的方法(AddRef,ReleaseQueryInterface)。私有成员变量m_nRefCount是用来保持对象生命期的,他不被直接的自加/减的,而是我们亲自使用线程安全的方法,使用API函数InterlockedIncrement InterlockedDecrement

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

HRESULT __stdcall CAddObj::QueryInterface(

                                    REFIID riid ,

                                    void **ppObj)

    {

    if (riid == IID_IUnknown)

        {

        *ppObj = static_cast(this) ;

        AddRef() ;

        return S_OK;

        }

    if (riid == IID_IAdd)

        {

        *ppObj = static_cast(this) ;

        AddRef() ;

        return S_OK;

        }

    *ppObj = NULL ;

    return E_NOINTERFACE ;

    }

ULONG   __stdcall CAddObj::AddRef()

    {

    return InterlockedIncrement(&m_nRefCount) ;

    }

ULONG   __stdcall CAddObj::Release()

    {    

    long nRefCount=0;

    nRefCount=InterlockedDecrement(&m_nRefCount) ;

    if (nRefCount == 0) delete this;

    return nRefCount;

    }

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

第六步 类工厂

我们已经完成了Add COM对象的部分功能。作为每一个COM的准则,每个COM对象必须有一个独立的IClassFactory实现。客户将使用这个接口得到我们IAdd接口实现的实例。IClassFactory接口,像所有其他COM接口一样,继承自IUnknown。因此我们也必须提供一个IUnknown的实现,以及IClassFactory的方法(LockServer CreateInstance)。创建一个新文件(命名为AddObjFactory.h)。声明一个类CAddFactory并使之继承自IClassFactory

class CAddFactory : public IClassFactory

    {

    public:

    HRESULT __stdcall QueryInterface(

                                REFIID riid ,

                                void **ppObj);

    ULONG   __stdcall AddRef();

    ULONG   __stdcall Release();

    HRESULT __stdcall CreateInstance(IUnknown* pUnknownOuter,

                                             const IID& iid,

                                             void** ppv) ;

    HRESULT __stdcall LockServer(BOOL bLock) ;

    private:

    long m_nRefCount;

    };

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