`
qiezi
  • 浏览: 497265 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

C++实现简单的类型库

    博客分类:
  • c++
阅读更多
很久以前看到有人问“如何在C++中实现动态加载类”时,简单地做了一个。

不过当时没有去考虑动态加载DLL的情况。

今天在cpp@codingnow.com中也有人问到这个问题,就把它给做完了。

当然只是简单地做到了“从全局类型库中,根据类名创建实例,支持动态DLL加载”,说得更明白点:

在应用程序App1中,向全局类型库中注册一个类型"Test",在另一个隐式链接的DLL中(即App1一启动就加载的DLL),向全局类型库中注册另外几个类型。这时可以在App1中通过类型的名字生成实例。

在另一个显式加载的DLL中(即调用LoadLibrary加载),向全局类型库中注册其它几个类型。这时通过LoadLibrary加载这个DLL,就可以生成这几个类型的实例了。

这地方不能上传文件,就把代码贴一点吧:

typelib.h文件:

#ifndef __TYPE_LIB_H__
#define __TYPE_LIB_H__

typedef 
void*(*CREATE_FUNC)();
typedef 
void(*RELEASE_FUNC)(void*);

void regtype (const char* name, CREATE_FUNC cfunc, RELEASE_FUNC rfunc);

void* createObject (const char* name);

void releaseObject (const char* name, void* p);

struct ITestInterface
{
    
virtual ~ITestInterface () {}
    
virtual void print () const = 0;
};

template 
<class T>
void* create ()
{
    
return new T;
}

template 
<class T>
void release (void* p)
{
    delete (T
*)p;
}

#endif // __TYPE_LIB_H__

typelib.cpp文件:

#include "typelib.h"

#include 
<string>
#include 
<map>
using namespace std;

namespace TypeRegistry
{
    
static map < string, pair<CREATE_FUNC, RELEASE_FUNC> >  types_info;

    template 
<class T>
    
void regType (const string& name)
    {
        types_info.insert (make_pair(name, make_pair(create
<T>, release<T>)));
    }
}

void regtype (const char* name, CREATE_FUNC cfunc, RELEASE_FUNC rfunc)
{
    TypeRegistry::types_info.insert (make_pair(name, make_pair(cfunc, rfunc)));
}

void* createObject (const char* name)
{
    map 
< string, pair<CREATE_FUNC, RELEASE_FUNC> >::const_iterator iter;
    iter 
= TypeRegistry::types_info.find (name);
    
if (iter != TypeRegistry::types_info.end ())
        
return (*iter->second.first)();
    
return NULL;
}

void releaseObject (const char* name, void* p)
{
    map 
< string, pair<CREATE_FUNC, RELEASE_FUNC> >::const_iterator iter;
    iter 
= TypeRegistry::types_info.find (name);
    
if (iter != TypeRegistry::types_info.end ())
        (
*iter->second.second)(p);
}

把它编译成静态lib或DLL,就可以使用了。

在那2个为我们提供类型的DLL中,DllMain函数中加入下面的代码:

// FirstTest和SecondTest是2个类名
regtype("FirstTest", create<FirstTest>, release<FirstTest>);
regtype(
"FirstTest", create<SecondTest>, release<SecondTest>);

就可以向全局类型库中注册类型。注意在类型库中是没有保存类信息的,所以最好是使用单根类库来做。

下面是一点测试代码:

int main()
{
       
// 程序启动时注册类型。
       
// 实际上启动时就加载了另一个动态链接库,那里面有3个类型,所以现在有4个类型
       regtype ("MyTest", create<MyTest>, release<MyTest>);
       
while (1)
       {
               
string class_name;
               cin 
>> class_name;
               
if (class_name == "q")
                       
break;
               
// 当输入load时,把另一个动态链接库加载进来,那个链接库中有2个类型,现在共有6个类型可用。
               if (class_name == "load")
               {
                       LoadLibrary(
"typelibdll_test.dll");
                       
continue;
               }
               ITestInterface
* test = (ITestInterface*)createObject (class_name.c_str());
               
if (!test)
               {
                       cout 
<< "This type not found" << endl;
                       
continue;
               }
               test
->print ();
               releaseObject (class_name.c_str(), test);
       }
       
return 0;
}

还有一个没考虑的地方,就是没有给它加锁,因为有可能在一个线程中加载一个DLL。

不过我还有些怀疑这东西是否真的有用?
分享到:
评论

相关推荐

    简单的编译器(c++实现)

    本项目“简单的编译器(C++实现)”旨在通过C++编程语言来构建一个基本的编译器,使初学者能理解编译器的工作原理,并具备实际编写编译器的能力。下面我们将深入探讨编译器的基本概念、结构和实现过程。 一、编译器...

    C++库封装JNI接口-实现java调用c++

    `System.loadLibrary()`加载名为"cppLib"的本地库,该库包含了实际的C++实现。 2. **生成JNI头文件**:使用`javah`工具(在Java SDK中)从Java源代码生成JNI头文件,例如`MyNativeClass.h`。这个头文件包含了Java...

    C++实现telnet代码

    根据提供的文件信息,本文将详细解析“C++实现Telnet代码”的相关知识点,包括Telnet协议的基本概念、C++编程语言的特点以及如何使用C++来实现一个简单的Telnet客户端。 ### Telnet协议简介 Telnet(Teletype ...

    文件系统C++实现

    本文将深入探讨一个用C++实现的文件系统模拟器,该系统能够执行常见的文件操作,如创建、删除和修改文件,并且采用了树形结构和位示图来管理磁盘空间。 首先,我们来看“文件系统”的概念。文件系统是一种逻辑组织...

    C++操作word和excel所需类型库文件

    标题中的"C++操作word和excel所需类型库文件"指的是在C++项目中,我们并不需要通过类向导(Class Wizard)引入特定的类型库(.tlb或.idl文件),而是可以直接引用相应的头文件,然后使用`using namespace`语句来简化...

    C++实现tlv编解码

    首先,`tlv`是这个项目的重点,它代表了C++实现的TLV编解码功能。项目可能包含了一个名为`tlv`的库或者模块,提供了处理TLV数据的API。在这个实现中,`multimap`是关键的数据结构,它是C++ STL(标准模板库)中的一...

    C++实现SIP协议栈

    在C++实现中,需要集成OpenSSL库来处理安全连接和验证。 8. **错误处理与调试**:完善的错误处理机制是任何协议栈的关键部分,包括异常处理、日志记录和调试接口,以便于排查问题。 在实际项目中,你可能会使用...

    C++ 实现WebSocket 服务器

    在本项目中,我们使用C++来实现一个WebSocket服务器,借助了libuv库来处理TCP层面的基础工作,并利用gbase作为辅助工具。 ### C++ 语言特性 C++是一种静态类型的、编译式的、通用的、大小写敏感的、不仅支持过程化...

    c++实现Ftp服务器

    使用C++实现FTP服务器需要使用Winsock库来实现网络通信。首先,需要启动Winsock库,协商Winsock的版本支持并分配必要的资源。然后,创建套接字,绑定端口,监听连接,接受连接,发送和接收数据,关闭套接字等。 ...

    c++实现的sip协议栈invite流程源码

    本篇将详细解析基于C++实现的SIP协议栈中的Invite流程源码。 首先,我们要了解SIP协议的基本流程,Invite请求是SIP中建立呼叫的核心过程。它通常由呼叫发起者(UAC,User Agent Client)发送给呼叫接收者(UAS,...

    websocket 客户端 服务器 c c++实现

    WebSocket是一种在...总的来说,这个C/C++实现的WebSocket模块为开发者提供了一种简单易用的工具,用于快速构建基于WebSocket的应用。通过理解和使用这个模块,开发者可以专注于应用逻辑,而无需深入底层协议细节。

    C++实现HTTP请求

    总之,C++实现HTTP请求是一个涉及网络编程、协议解析等多个技术层面的问题。通过`HttpClient`类,我们可以简化这一过程,专注于业务逻辑,而不是底层的网络通信细节。在阅读和理解"HttpClient.cpp"和"HttpClient.h...

    C++实现CNN识别手写数字

    总之,C++实现CNN识别手写数字涉及多个步骤,包括选择合适的库、数据预处理、模型设计、训练和评估。这个过程既考验编程技巧,也要求对深度学习理论有深入理解。通过实践,你可以掌握这一技术,并将其应用于更广泛的...

    SMTP 简单邮件发送系统 C++语言实现

    C++实现时,可能需要集成OpenSSL库来处理加密连接。 6. **多线程或异步处理**:为了提高性能,邮件发送系统可能需要同时处理多个邮件任务,这可以通过多线程或异步I/O来实现。例如,使用std::thread或Boost.Thread...

    c c++实现http服务 c c++开发restful api服务

    要使用C或C++实现HTTP服务,你需要理解HTTP协议的基本原理,包括请求行、请求头、请求体以及响应的构成。通常,这涉及到解析HTTP请求,生成响应,处理不同类型的HTTP方法,以及管理连接状态。一个简单的HTTP服务器...

    HDLC协议的C++程序实现实例

    下面将详细阐述HDLC协议的关键概念及其C++实现的关键点。 1. HDLC帧结构: HDLC帧由固定部分和可变部分组成。固定部分包括同步字段、地址字段、控制字段和帧校验序列(FCS),可变部分为信息字段。在C++实现时,...

    SNL语言编译器C++实现

    《SNL语言编译器C++实现:从词法分析到目标代码生成》 在编程领域,编译器是至关重要的工具,它将高级语言(如SNL)转化为机器可以理解的目标代码。本文将深入探讨SNL语言编译器的C++实现过程,包括词法分析、语法...

    C++实现的BOSN bson-cpp的编译

    BSON-cpp是C++实现的一个库,允许开发者在C++项目中方便地处理BSON数据。本篇文章将详细介绍如何在C++环境下编译和使用BOSN提供的bson-cpp库。 首先,我们需要确保我们的开发环境中已经安装了必要的依赖。对于BSON-...

    C++98、C++03、C++11、C++14、C++17、C++20的CHM查询文档

    C++ 标准库头文件 具名要求 功能特性测试 (C++20) 工具库 类型支持(基本类型、RTTI、类型特性) 概念库 (C++20) 错误处理 动态内存管理 日期和时间工具 字符串库 容器库 迭代器库 范围库 (C++20) 算法库 数值库 ...

    C++实现的西门子S7-200 PPI通讯

    ### C++实现的西门子S7-200 PPI通讯 #### 一、引言 西门子S7-200是一款小型可编程逻辑控制器(PLC),广泛应用于工业自动化领域。该PLC提供了多种通讯方式,其中PPI(Point-to-Point Interface)协议是一种简单且...

Global site tag (gtag.js) - Google Analytics