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

推荐订阅源

G
Google Developers Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
宝玉的分享
宝玉的分享
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - Franky
IT之家
IT之家
S
SegmentFault 最新的问题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
T
Threatpost
Cyberwarzone
Cyberwarzone
AWS News Blog
AWS News Blog
博客园 - 司徒正美
C
Cyber Attacks, Cyber Crime and Cyber Security
Latest news
Latest news
S
Secure Thoughts
S
Schneier on Security
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
C
Cisco Blogs
Attack and Defense Labs
Attack and Defense Labs
S
Security Affairs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Hacker News: Ask HN
Hacker News: Ask HN
大猫的无限游戏
大猫的无限游戏
博客园_首页
S
Security @ Cisco Blogs
C
CXSECURITY Database RSS Feed - CXSecurity.com
A
Arctic Wolf
AI
AI
Last Week in AI
Last Week in AI
Hugging Face - Blog
Hugging Face - Blog
Project Zero
Project Zero
P
Proofpoint News Feed
T
Tor Project blog
P
Privacy International News Feed
阮一峰的网络日志
阮一峰的网络日志
博客园 - 聂微东
月光博客
月光博客
Forbes - Security
Forbes - Security
量子位
I
Intezer
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Y
Y Combinator Blog
P
Proofpoint News Feed
T
The Exploit Database - CXSecurity.com
腾讯CDC
N
Netflix TechBlog - Medium
www.infosecurity-magazine.com
www.infosecurity-magazine.com
L
Lohrmann on Cybersecurity
T
Tailwind CSS Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC

博客园 - 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 Create com step by step.1
Create COM step by step 2.
abraham · 2004-03-31 · via 博客园 - abraham

第七步 实现IClassFactory的方法

实现类CAddFactory的方法。创建一个新文件(AddObjFactory.cpp)。提供类IUnknownIClassFactory的方法实现。AddRef,ReleaseQueryInterface方法实现和前面类CAddObj中这三个函数实现基本一样。在方法CreateInstance中,类CaddObj被实例化并且传回其接口指针。LockServer方法没有给出细节的实现。

HRESULT __stdcall CAddFactory::CreateInstance(IUnknown* pUnknownOuter,

                                           const IID& iid,

                                           void** ppv)

    {

    if (pUnknownOuter != NULL)

        {

        return CLASS_E_NOAGGREGATION ;

        }

    CAddObj* pObject = new CAddObj ;

    if (pObject == NULL)

        {

        return E_OUTOFMEMORY ;

        }

    return pObject->QueryInterface(iid, ppv) ;

    }

HRESULT __stdcall CAddFactory::LockServer(BOOL bLock)

    {

    return E_NOTIMPL;

    }

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

第八步 实现DllGetClassObject的方法

一个进程内COM对象只是一个简单的WIN32DLL,他遵循既定的协议。每一个COM DLL必须有一个通过名字DllGetClassObject的出口函数。客户端将调用这个函数以得到类厂的接口(IUnknown or IClassFactory),之后就是调用CreateInstance方法。创建一个新文件(Exports.cpp),在其中实现DllGetClassObject。(代码如下)

STDAPI DllGetClassObject(const CLSID& clsid,

                         const IID& iid,

                         void** ppv)

    {

    if (clsid == CLSID_AddObject)

        {

        CAddFactory *pAddFact = new CAddFactory;

        if (pAddFact == NULL)

            return E_OUTOFMEMORY;

        else

            {

            return pAddFact->QueryInterface(iid , ppv);

            }

        }

    return CLASS_E_CLASSNOTAVAILABLE;

    }

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

第九步 实现DllCanUnloadNow

客户需要知道什么时候COM DLL可以被从内存中卸载。更进一步,一个进程内COM对象显示的通过调用API函数LoadLibrary装入内存中的客户程序的进程空间中。这个显示装载的DLL也可以使用FreeLibrary卸载。COM客户必须知道什么时候DLL可以被安全的卸载。一个客户必须确定没有任何来自于特别是DLL中的COM对象的实例仍在生命期中。要使得这个可以被简单的计算,在一个COM DLL中,我们在类CAddObjCAddFactory的构造函数中自加一个全局变量(g_nComObjsInUse)。类似的,在析构函数中,自减这个全局变量。

我们输出另一个COM规定的函数:DllCanUnloadedNow,实现如下:

STDAPI DllCanUnloadNow()

    {

    if (g_nComObjsInUse == 0)

        {

        return S_OK;

        }

    else

        {

        return S_FALSE;        }

}

第十步 DllRegisterServer UnregisterServer

COM对象的位置信息将会进入到注册表中。这个工作可以在外面通过一个.REG文件完成,也可以使用一个输出函数DllRegisterServer。要去除注册表的内容,我们将使用另一个输出函数DllUnregisterServer。这两个函数的实现在文件Registry.cpp中。一个简单的工具regsrv32.exe也可以用来装入一个指定的DLL并执行DllRegisterServer/DllUnregisterServer

要使得连接器输出这两个函数,我们将创建一个模块定义文件(Exports.def

;

;contains the list of functions that are being exported from this DLL

;

DESCRIPTION     "Simple COM object"

EXPORTS

                DllGetClassObject   PRIVATE

                DllCanUnloadNow    PRIVATE

                DllRegisterServer   PRIVATE

                DllUnregisterServer PRIVATE

第十一步

我们下面就给出最后完成我们AddObj Win32 DLL工程的绝技。将文件IAdd.idl插入到工程工作空间中。

为此文件设置自定义的编译选项。(如下图)

为了在每一次编译完成后执行regsrv32.exe,在"Post-bulid step"对话框中插入一个命令串如下图示:

编译这个DLL。将IDL文件插入到工程中是为了减少每一次文件被编辑后必须要执行外部编译。每次我们成功的编译我们的工程,这个COM对象就会被注册。

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

要从Visual Basic中使用AddObj COM 对象,创建一个简单的EXE工程,添加如下的代码。确定已经添加了对IAdd.tlb模板库的一个对象的引用。

Dim iAdd As CodeGuruMathLib.iAdd

    Set iAdd = CreateObject("CodeGuru.FastAddition")

    iAdd.SetFirstNumber 100

    iAdd.SetSecondNumber 200

MsgBox "total = " & iAdd.DoTheAddition()

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

如下是我们曾使用过的文件

IAdd.idl

接口定义文件的内容

AddObj.h

包含类 CAddObj 声明

AddObjFactory.h

包含类 CAddFactory 声明

AddObj.cpp

包含类CAddObj 实现

AddObj.cpp

包含类CAddFactory 实现

Exports.cpp

包含DllGetClassObject,DllCanUnloadNow & DllMain 的实现

Registry.cpp

包含r DllRegisterServer,DllUnregisterServer 的实现

AddObjGuid.h

包含我们 AddObj COM 对象的GUID

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

AddObj.dll一起,类型模板库也可以被发布。对于一个简单的进程,类型模板库IAdd.tlb可以作为二进制资源嵌入到AddObj.dll文件中。以后,仅仅将这个DLL文件AddObj.dll发布给客户就可以了。

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

通过如下的任一种方式,Visual C++客户可以使用这个COM接口

1#import “IAdd.tlb”

2IAdd.h头文件。在此情况下,这个DLL提供商必须将IAdd.hDLL文件一起发布。

3、使用一些工具向导生成c++代码(例如,MFC类向导)

在第一种情况下,编译器创建一些中间文件(.TLH,.TLI),这些文件中含有扩展的接口声明。此外,编译器也可以声明根据接口建立(bulit around the raw interfaces)智能指针类。对于COM程序员来说,通过适当的管理COM对象的生存期,智能指针类使生存期更容易(控制)。

下面的例子中,#import 来输入AddObj.dll文件,而不是IAdd.tlb,因为我们把TLB文件放到了DLL中(译者注,前面提到的将类型库作为二进制资源放到DLL资源中)。此外,#import也应该使用TLB文件。

Visual C++中,创建一个控制台EXE工程。键入(或拷贝)如下的内容并编译。

#include    <objbase.h>

#include    <stdio.h>

#import     "AddObj.dll"

void main()

    {

    long n1 =100, n2=200;       

    long nOutPut = 0;

    CoInitialize(NULL);

    CodeGuruMathLib::IAddPtr pFastAddAlgorithm;

    pFastAddAlgorithm.CreateInstance("CodeGuru.FastAddition");

    pFastAddAlgorithm->SetFirstNumber(n1);

    pFastAddAlgorithm->SetSecondNumber(n2);

    nOutPut = pFastAddAlgorithm->DoTheAddition();

    printf("\nOutput after adding %d & %d is %d\n",n1,n2,nOutPut);

    }