QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1284|回复: 8

c++共享库的问题,一直没搞明白!!!

[复制链接]
发表于 2006-4-6 15:09:04 | 显示全部楼层 |阅读模式
关于C++共享库的问题,我一直都没有弄明白,请大家帮帮忙解答一下我的问题:

        c++编写的类能放在动态共享库文件中吗?如果可以的话,有没有什么必须注意的事项?如何调用呢?
        c++编写的共享库中的函数或数据该怎样调用呢?

        请大家教教我好吗?很长时间了,这个问题老是搞不明白!谢谢您的回复!
        给些资料链接也可以呀!
发表于 2006-4-7 09:17:44 | 显示全部楼层
可以,但要包含原来的头文件
回复

使用道具 举报

发表于 2006-4-7 11:42:46 | 显示全部楼层
用c++写共享库和用c写共享库差别不大,不过如果你是动态载入共享库,比如用dlopen()函数,那么因为你只能从共享库中获得函数指针,所以你需要在共享库里写一个全局函数,通过这个全局函数来获得各个类的实例……
回复

使用道具 举报

 楼主| 发表于 2006-4-7 19:08:58 | 显示全部楼层
谢谢楼上两位朋友的回复!

sjinny:
     请问:动态载入共享库,必须要在共享库里写一个全局函数,通过这个全局函数来获得各个类的实例对象吗?那静态的共享库呢?感觉还不是很明白,能请你给些这方面的资料吗?谢谢了!!
回复

使用道具 举报

发表于 2006-4-7 23:40:57 | 显示全部楼层
库头文件
cpp_sp.h

[code:1]
#ifndef __CPP_SP_H__
#define __CPP_SP_H__

class cpp_sp {
public:
        cpp_sp();
        ~cpp_sp();

        void set_loc_var(int);
        int  get_loc_var();

        int pub_var;

private:
        int loc_var;
};

#endif // ! __CPP_SP_H__
[/code:1]

库的实现文件
cpp_sp.cpp
[code:1]
#include "cpp_sp.h"

cpp_sp::cpp_sp():pub_var(0), loc_var(0) {
        // constructor
}

cpp_sp::~cpp_sp(){
        // destructor
}

void cpp_sp::set_loc_var(int a){
        this->loc_var = a;
        return;  
}

int cpp_sp::get_loc_var() {
        return (this->loc_var );
}
[/code:1]

使用库的文件
main.cpp
[code:1]
#include <iostream>
#include "cpp_sp.h"

using namespace std;

int main(int argc, char** argv)
{
        cpp_sp obj;

        obj.set_loc_var(108);

        cout << " loc_var = " << obj.get_loc_var() << endl;

        obj.pub_var = 801;

        cout << " pub_var = " << obj.pub_var << endl;

        return 0;
}

[/code:1]

生成动态库libcpp_sp.so
[code:1]
g++ -o libcpp_sp.so -fPIC -shared cpp_sp.cpp
[/code:1]
然后把生成的文件拷贝到/usr/local/lib
为什么拷贝到哪里,这个涉及到一个很让人烦的问题,就是linux的ldconfig
程序,它负责从那找动态库文件,我这里简便起见,自己查ldconfig的使用
方法吧

生成调用动态库的可执行文件
[code:1]
g++ -o test main.cpp -L/usr/local/lib -lcpp_sp
[/code:1]

然后就执行
#./test

自己看结果吧。

依此类推,你应该能明白静态库也是一样的原理。
回复

使用道具 举报

 楼主| 发表于 2006-4-8 07:49:05 | 显示全部楼层
谢谢"kakuyou"版主的帮助!
还有一事不明,请再指点一下,谢谢!
三楼的"sjinny"说-------"如果你是动态载入共享库,比如用dlopen()函数,那么因为你只能从共享库中获得函数指针,所以你需要在共享库里写一个全局函数,通过这个全局函数来获得各个类的实例"     对于这句话应该如何理解?
回复

使用道具 举报

发表于 2006-4-8 12:17:44 | 显示全部楼层
copy一份:
4. 动态加载的函数库Dynamically Loaded (DL) Libraries

动态加载的函数库 Dynamically loaded (DL) libraries是一类函数库,它可以在程序运行过程中的任何时间加载。它们特别适合在函数中加载一些模块和plugin扩展模块的场合,因为它可以在当程序需要某个plugin模块时才动态的加载。例如,Pluggable Authentication Modules(PAM)系统就是用动态加载函数库来使得管理员可以配置和重新配置身份验证信息。

Linux系统下,DL函数库与其他函数库在格式上没有特殊的区别,我们前面提到过,它们创建的时候是标准的object格式。主要的区别就是这些函数库不是在程序链接的时候或者启动的时候加载,而是通过一个API来打开一个函数库,寻找符号表,处理错误和关闭函数库。通常C语言环境下,需要包含
这个头文件。

Linux中使用的函数和Solaris中一样,都是dlpoen() API。当时不是所有的平台都使用同样的接口,例如HP-UX使用shl_load()机制,而Windows平台用另外的其他的调用接口。如果你的目的是使得你的代码有很强的移植性,你应该使用一些wrapping函数库,这样的wrapping函数库隐藏不同的平台的接口区别。一种方法是使用 glibc函数库中的对动态加载模块的支持,它使用一些潜在的动态加载函数库界面使得它们可以夸平台使用。具体可以参考http: //developer.gnome.org/doc/API/glib/glib-dynamic-loading-of-modules.html. 另外一个方法是使用libltdl,是GNU libtool的一部分,可以进一步参考CORBA相关资料。

4.1. dlopen()

dlopen函数打开一个函数库然后为后面的使用做准备。C语言原形是:

void * dlopen(const char *filename, int flag);

如果文件名filename是以“/”开头,也就是使用绝对路径,那么dlopne就直接使用它,而不去查找某些环境变量或者系统设置的函数库所在的目录了。否则dlopen()

就会按照下面的次序查找函数库文件:

1. 环境变量LD_LIBRARY指明的路径。
2. /etc/ld.so.cache中的函数库列表。
3. /lib目录,然后/usr/lib。不过一些很老的a.out的loader则是采用相反的次序,也就是先查/usr/lib,然后是/lib。

Dlopen ()函数中,参数flag的值必须是RTLD_LAZY或者RTLD_NOW,RTLD_LAZY的意思是resolve undefined symbols as code from the dynamic library is executed,而RTLD_NOW的含义是resolve all undefined symbols before dlopen() returns and fail if this cannot be done’。

如果有好几个函数库,它们之间有一些依赖关系的话,例如X依赖Y,那么你就要先加载那些被依赖的函数。例如先加载Y,然后加载X。

dlopen()函数的返回值是一个句柄,然后后面的函数就通过使用这个句柄来做进一步的操作。如果打开失败dlopen()就返回一个NULL。如果一个函数库被多次打开,它会返回同样的句柄。

如果一个函数库里面有一个输出的函数名字为_init,那么_init就会在dlopen()这个函数返回前被执行。我们可以利用这个函数在我的函数库里面做一些初始化的工作。我们后面会继续讨论这个问题的。

4.2. dlerror()

通过调用dlerror()函数,我们可以获得最后一次调用dlopen(),dlsym(),或者dlclose()的错误信息。

原文在
http://linux.21ds.net/2001/08/21/225eb4ae52f16a4d3dd97e80f7e65ef5/
楼主也可以看下man dlopen
回复

使用道具 举报

发表于 2006-4-8 12:52:33 | 显示全部楼层
[quote:8bcd55fe54="jiandaoxu"]谢谢"kakuyou"版主的帮助!
还有一事不明,请再指点一下,谢谢!
三楼的"sjinny"说-------"如果你是动态载入共享库,比如用dlopen()函数,那么因为你只能从共享库中获得函数指针,所以你需要在共享库里写一个全局函数,通过这个全局函数来获得各个类的实例"     对于这句话应该如何理解?[/quote]

上面的说法其实是说用C++写库的实现,然后把对象处理写在一个C函数里,
然后你的主程序调用那个C函数,这个时候,库是用C++写的还是C写的对
你的主程序来说都不重要,一律认为它是个C的库。

当然,我介绍的方法系统实际上最终还是要调用dlopen这样的函数,只不过编译
器自动为你生成了代码,你就不需要自己再花时间写
回复

使用道具 举报

 楼主| 发表于 2006-4-8 14:48:30 | 显示全部楼层
再次感谢两位的相助! 大体上明白了.

"kakuyou"版主--------你说:"当然,我介绍的方法系统实际上最终还是要调用dlopen这样的函数,只不过编译器自动为你生成了代码,你就不需要自己再花时间写"-------能展开来解释一下吗?谢谢!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-2 18:27 , Processed in 0.044426 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表