ACE_DLL封装了操作系统对dll的操作,因为Windows和*nix对dll操作的接口不一致,如Windows使用LoadLibrary/GetProcAddress/FreeLibrary这三个函数来显示地加载dll,从dll中找到函数地址以及关闭dll,而Linux则使用dlopen/
dlsym/dlclose做同样的事情,ACE要使得程序具有良好的跨平台特性就需要屏蔽这些平台的差异性,而向上呈现出统一的接口。
下面这个例子展示了如何使用ACE_DLL类来操作dll。
//dll_impl.h
#include <iostream>
#include <string>
using namespace std;
class person
{
public:
person(const string& name, unsigned int age);
~person();
string get_person_name() const;
private:
string m_name;
unsigned int m_age;
};
//向外暴露这个接口,使用" extern "C" "来声明之,否则待会儿调用symbol来获取
//本函数的地址时就必须填写mingle之后的全名
extern "C" person create_person(const string& name, unsigned int age);
//dll_impl.cpp
#include "dll_impl.h"
person::person(const string& name, unsigned int age) : m_name(name), m_age(age)
{
cout << m_name << " say hello!" << endl;
};
person::~person()
{
cout << m_name << " say byebye!" << endl;
};
string person::get_person_name() const {return m_name;}
person create_person(const string& name, unsigned int age)
{
return person(name, age);
};
//main函数
#include "ace/Log_Msg.h"
#include "ace/DLL.h"
#include "ace/ACE.h"
#include "dll_impl.h"
int main()
{
ACE_DLL dll;
int retval = dll.open("libperson.so", ACE_DEFAULT_SHLIB_MODE, 1);
if (retval != 0)
{
ACE_TCHAR *dll_error = dll.error ();
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Error in DLL Open: %s\n"),
dll_error ? dll_error : ACE_TEXT ("unknown error")),
-1);
}
else
{
ACE_DEBUG((LM_DEBUG, "open the dll successfully!!!\n"));
}
//声明一个函数指针类型
typedef person (*person_factory)(const string& name, unsigned int age);
person_factory fac = (person_factory)dll.symbol("create_person");
if(fac == NULL)
{
cout << "get symbol failed!" << endl;
return -1;
}
person per = fac("ecy", 24);
cout << per.get_person_name() << endl;
dll.close();
return 0;
}
编译过程如下:
1、首先生成动态链接库
g++ -shared -o libperson.so dll_impl.cpp
2、生成测试程序
g++ -g -o dll_test dll_test.cpp -L. -lperson -lACE
3、设置LD_LIBRARY_PATH
export LD_LIBRARY_PATH=.
这一步是很重要的,否则即便是dll_test同libperson.so放置在同一路径下,运行dll_test时仍然会提示找不到该动态链接库,这个错误让我郁闷了好久。
测试程序运行结果如下:
ecy@ecy-geek:~/ACE/ace_dll$ ./dll_test
open the dll successfully!!!
ecy say hello!
ecy
ecy say byebye!
http://fuzhijie.me
下面这个例子展示了如何使用ACE_DLL类来操作dll。
//dll_impl.h
#include <iostream>
#include <string>
using namespace std;
class person
{
public:
person(const string& name, unsigned int age);
~person();
string get_person_name() const;
private:
string m_name;
unsigned int m_age;
};
//向外暴露这个接口,使用" extern "C" "来声明之,否则待会儿调用symbol来获取
//本函数的地址时就必须填写mingle之后的全名
extern "C" person create_person(const string& name, unsigned int age);
//dll_impl.cpp
#include "dll_impl.h"
person::person(const string& name, unsigned int age) : m_name(name), m_age(age)
{
cout << m_name << " say hello!" << endl;
};
person::~person()
{
cout << m_name << " say byebye!" << endl;
};
string person::get_person_name() const {return m_name;}
person create_person(const string& name, unsigned int age)
{
return person(name, age);
};
//main函数
#include "ace/Log_Msg.h"
#include "ace/DLL.h"
#include "ace/ACE.h"
#include "dll_impl.h"
int main()
{
ACE_DLL dll;
int retval = dll.open("libperson.so", ACE_DEFAULT_SHLIB_MODE, 1);
if (retval != 0)
{
ACE_TCHAR *dll_error = dll.error ();
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Error in DLL Open: %s\n"),
dll_error ? dll_error : ACE_TEXT ("unknown error")),
-1);
}
else
{
ACE_DEBUG((LM_DEBUG, "open the dll successfully!!!\n"));
}
//声明一个函数指针类型
typedef person (*person_factory)(const string& name, unsigned int age);
person_factory fac = (person_factory)dll.symbol("create_person");
if(fac == NULL)
{
cout << "get symbol failed!" << endl;
return -1;
}
person per = fac("ecy", 24);
cout << per.get_person_name() << endl;
dll.close();
return 0;
}
编译过程如下:
1、首先生成动态链接库
g++ -shared -o libperson.so dll_impl.cpp
2、生成测试程序
g++ -g -o dll_test dll_test.cpp -L. -lperson -lACE
3、设置LD_LIBRARY_PATH
export LD_LIBRARY_PATH=.
这一步是很重要的,否则即便是dll_test同libperson.so放置在同一路径下,运行dll_test时仍然会提示找不到该动态链接库,这个错误让我郁闷了好久。
测试程序运行结果如下:
ecy@ecy-geek:~/ACE/ace_dll$ ./dll_test
open the dll successfully!!!
ecy say hello!
ecy
ecy say byebye!
http://fuzhijie.me