`
qiezi
  • 浏览: 491394 次
  • 性别: 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。

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

相关推荐

    linux下C++动态链接C++库示例

    文中是linux下 C++动态库 实现接口提供类导出的一个例子 注意其中使用函数返回基类指针的用法,因为Linux的动态链接库不能像MFC中那样直接导出类 一、介绍 如何使用dlopen API动态地加载C++函数和类,是Unix C++...

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

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

    .ini文件解析器(C++ 标准库实现)

    纯C++标准库实现,仅用到了&lt;fstream&gt;&lt;map&gt;&lt;list&gt;&lt;string&gt;,这些标准库,没有在Linux下测试过。(简易实现,代码部分仅6K,全采用string类型) /* .ini 文件 解析器【只能读取】 Section和Key只能为字母、数字、...

    基于模板、类型安全、通用的观察者模式的C++实现

    Implementation of Template-based, type-safe and generic Observer Pattern for C++基于模板、类型安全、通用的观察者模式的C++实现;包含库文件和使用示例。

    C++调用C#实现Xml读写

    C++调用C#实现Xml读写,简单来说就是C++利用C#对Xml的Dom文档对象操作方式来实现xml的读写,涉及C++调用C#的Dll动态库,C++与C#的部分类型转换。详见空间博客。

    C++EasyX图形库png格式图片实现透明贴图源代码及使用方法

    本算法可以在Microsoft Visual Studio并且安装了EasyX图形库的前提下实现功能。 同时要学习C++图形库相关的知识,也可以点击我的主页,找到EasyX专栏进行图形库的学习。 值得注意的是,在使用本算法时需要调用...

    一个C++实现的源代码行数统计工具

    统计你的工程的代码行数,可以设置过滤的文件类型,支持批量添加文件,用Visual C++开发。 该工具用来统计你的工程的代码行数。可设置是否计算空行,可配置过滤的文件类型。 支持以目录添加或以文件添加,如果以...

    c++参考手册 2018版

    类型支持 − 特性 (C++11) 程序工具 关系运算符 (C++20) numeric_limits − type_info initializer_list (C++11) 概念库 (C++20) 诊断库 通用工具库 智能指针与分配器 日期和时间 函数对象 − hash (C++11) ...

    数据结构》抽象数据类型模板库及常用算法的面向对象C++实现毕业论文.docx

    数据结构》抽象数据类型模板库及常用算法的面向对象C++实现毕业论文.docx

    QQ课程设计 c++实现

    各微X之间只要有一个服务登录,则其它服务简单确认后视为自动登录。 6、功能展示要求(main函数) (1)设计约定。开通服务情况、群成员信息和好友信息可以预先保存到文件中,在系统启动时将这些信息加载到内存中;...

    c++模板元编程详解

    大致限于泛型编程,但一些系统级的代码,尤其是对通用性、性能要求极高的基础库(如 STL、Boost)几乎不可避免的都大量地使用 C++ 模板,一个稍有规模的大量使用模板的程序,不可避免的要涉及元编程(如类型计算)。...

    使用c++实现boost::any类

    使用c++实现boost::any类 any类可以存放任意类型数据,如: void test_any() { any any_a1(123); int a2 = any_cast(any_a1); int* p_a2 = any_cast(&any_a1); std::cout *p_a2="*p_a2; any any_b1(12.35); ...

    基于C++实现的语义分析系统

    语义分析主要完成两个任务,其一是构建符号表,二是进行类型检查。 首先,需要把语法分析生成的语法树读入,然后真的搭建成一棵树型结构。 然后,对树形结构上的每一个节点进行递归遍历,在此过程中进行类型检查与...

    如何使用JNA调用本地C/C++动态链接库详细示例代码

    详细演示了如何通过JNA实现以下形式的动态链接库接口: 1:基本数据类型 2:基本数据类型的指针和引用 3:结构体 4:结构体的指针和引用 5:函数指针和回调函数 6:字符串指针 7:输入一个数组 8:输出一个数组并...

    基于C++实现简易图书管理系统.zip

    管理系统是一种通过计算机技术实现的用于组织、监控和控制各种活动的软件系统。这些系统通常被设计用来提高效率、减少错误、加强安全性,同时提供数据和信息支持。以下是一些常见类型的管理系统: 学校管理系统: ...

    dtl, 由 C++ 编写的diff模板库.zip

    dtl, 由 C++ 编写的diff模板库 dtl dtl 是用 C++ 编写的diff模板库。 模板的NAME 是 C++的模板。目录特性正在开始运行。比较两个字符串。比较两个数据具有任意类型。合并三个序列。补丁函数差异作为统一格式比较大...

    Advanced.C++.Programming.Styles.and.Idioms (Advanced C++中文版)

    提供了大量面向对象设计转换成C++实现的准则。 .展示了如何用模板支持可重用性。 .描述了重要的大型系统开发问题,包括库结构的设计、异常处理和分布式处理。 . 本书是C++系统程序员或应用程序员工作的必备手册。 ...

    在c++中实现属性

    大多数在C++实现属性的库和编译器使用扩展技术,如Managed C++或C++ Builder,或者他们使用如通常函数的set和get方法,但那不是属性。 详述 我们首先看一下什么是属性。一个属性表现为一个字段或者成员变量,但它...

    吉他店程序实现 C++

    一共有四个类,不仅可以卖吉他,还有其他类的乐器可以出售,而且,要提供初始化库存信息,所以用了TXT文件输入输出,比较简单,还有可以根据不同的属性查询乐器,有:名称,价格,制造商,背板材料,模型,类型等,...

Global site tag (gtag.js) - Google Analytics