首页 > 代码库 > AutoSharedLibrary -- 基于模板元编程技术的跨平台C++动态链接载入库

AutoSharedLibrary -- 基于模板元编程技术的跨平台C++动态链接载入库

 基于模板元编程技术的跨平台C++动态链接载入库。通过模板技术,使用者仅需通过简单的宏,就可以使编译器在编译期自己主动生成载入动态链接库导出符号的代码,无不论什么额外的执行时开销。


extern "C"
{
    typedef int(*Proc_fnTestDll)();
    typedef const char* (*Proc_fnTestDll2)(const char*);
}


ASL_LIBRARY_BEGIN(Test)
    // 强制载入名为fnTestDll的接口,假设没有该接口。则抛SymbolNotFound异常
    ASL_SYMBOL_EXPLICIT(Proc_fnTestDll, fnTestDll)
 // 载入名为<span style="font-family: Arial, Helvetica, sans-serif;">fnTestDll2的接口,假设没有该接口,则为NULL</span>
ASL_SYMBOL_OPTIONAL(Proc_fnTestDll2, fnTestDll2)
// 载入名为shouldFail的接口,假设没有该接口。则为NULL</span>
ASL_SYMBOL_OPTIONAL(Proc_fnTestDll2, shouldFail) // non-exists
    // 载入名为testFunc的接口,接口函数的类型由调用时的实參类型决定
    ASL_SYMBOL_EXPLICIT_T(testFunc) // Enabled only when ‘ #define  ASL_USE_CPP11 1 ‘ and compliler supports c++ 11
ASL_LIBRARY_END()

int _tmain(int argc, _TCHAR* argv[])
{
    using namespace std;

    Test test;

    try {
        test.Load(_T("testDll.dll"));
    }
    catch (const ASL::LibraryNotFoundException& e)
    {
        cout << "Lib not found " <<  e.what() << endl;
    }
    catch (const ASL::SymbolNotFoundException& e) {
        cout << "Sym not found " <<  e.what() << endl;
    }

    assert(test.shouldFail == NULL);
    cout << test.fnTestDll() << endl;
    cout << test.fnTestDll2("hELLO, WORLD") << endl;
 // testFunc函数的签名由此处的实參类型推导出来,int为其返回值类型,
    // 这样的调用方式并不安全。慎用!
   cout << test.testFunc<int>(ASL_ARGS_T((int)1, (int)2.f)) << endl;
   test.Unload();
   getchar();
   return 0;
}


ASL_SYMBOL宏的第三个參数表示。假设该符号载入失败(模块并没有导出该接口),是否抛出SymbolNotFoundException。 为false时,抛出异常,终止链接库载入流程,而且e.what()为载入失败的符号名称。为true时,忽略错误,仍然继续载入其它符号。client能够依据相应的接口是否为NULL来推断该符号是否载入成功。

/********************************************************************
	created:	2014/05/31
	file base:	AutoSharedLibrary
	file ext:	h
	author:		qiuhan (hanzz2007@hotmail.com)

	purpose:	Cross platform classes and macros to make dynamic loaded module
	easy to use by using c++ template meta-programming technic.

	No need to make any changes to existing module code.

	Support both windows(*.dll) and linux(*.so) platforms (wchar_t & char).

	SPECIAL THANKS TO TRL (Template Relection Library)

	usage:
	Following codes are all in client side:

	ASL_LIBRARY_BEGIN(ClassName)
		ASL_SYMBOL_OPTIONAL(Func1Type, func1)
		ASL_SYMBOL_EXPLICIT(Func2Type, func2)
		// Enabled only when ‘ #define  ASL_USE_CPP11 1 ‘ and compliler supports c++ 11
		ASL_SYMBOL_EXPLICIT_T(func4) // only need to declare the name
	ASL_LIBRARY_END()

	ClassName theLib;
	try {
	theLib.Load("./1.so");
	}
	catch (LibraryNotFoundException& e) {
	}
	catch (SymbolNotFoundException& e) {
	}
	theLib.func1(1);
	theLib.func2("aa");

	// The function type is deduced with the args
	// retType => int, args => const char* AND float
	// So this calling is UNSAFE!
	// You‘d better explicitly specifiy the type of args like this
	theLib.func4<int>(ASL_ARGS_T((const char*)"test", (float)2.3));

	theLib.Unload();


*********************************************************************/

#ifndef ASL_INCLUDE_H
#define  ASL_INCLUDE_H

#ifdef WIN32
#include <windows.h>
#else
#include <dlfcn.h>
#endif


#include <cstdlib>
#include <exception>
#include <string>

#if ASL_USE_CPP11
#include <functional>
#include <tuple>
#endif


namespace ASL {

	namespace Private {

		template <class Head_, class Tail_>
		struct TypeList
		{
			typedef Head_ Head;
			typedef Tail_ Tail;
		};

		class NullType {};

		template <int i_>
		struct Int2Type
		{
			enum { value = http://www.mamicode.com/i_ };>




AutoSharedLibrary -- 基于模板元编程技术的跨平台C++动态链接载入库