linux下创建,使用动态库

来源:互联网 发布:淘宝快递拒签要运费吗 编辑:程序博客网 时间:2024/06/05 16:45

1. 现在要生成libmydll.so的库文件,头文件如下

#ifndef  _MYDLL_H
#define  _MYDLL_H
#include "stdio.h"

#ifdef WIN32
    #ifdef MYDLL_EXPORTS
        #define MYDLLAPI  extern "C" __declspec(dllexport)
    #else
        #define MYDLLAPI  extern "C" __declspec(dllimport)
    #endif
#else
    #define MYDLLAPI extern "C"
#endif


#define MAXBUFLEN  0x1000000

MYDLLAPI  int Add(int x, int y);
MYDLLAPI  int TestWrite(char *p, int buflen = MAXBUFLEN);

#endif

命令:  g++ mydll.cpp -fPIC -shared -o libmydll.so

-shared表示生成共享库, -fPIC表示生成的库可以重入

 

2. 如果依赖头文件, 则使用 -I +路径包括

 g++  -o ../yu.a  yu.cpp -I../../     //在上一级的目录上生成yu.a

 

3.这里如果动态库与cpp不在同一个目录下,就是用-L + 动态库的路径。

g++ main.cpp -I../../mydll -L../../mydll -lmydll -o main.a

或者 g++ main.cpp -I../../mydll  ../../mydll/libmydll.so  -o main.a也可以,但是名称必须是 libmydll.so这样有前缀的,否则错误

当依赖多个动态库的时候,依次加上动态库就可以了

 g++ main.cpp -I../../mydll -I../../JTFS -L../../mydll -lmydll -L../../JTFS -ljtfs -o main.a或者写成

 g++ main.cpp -I../../mydll -I../../JTFS -L../../mydll -L../../JTFS -ljtfs -lmydll  -o main.a

注意,这里还要将库加到环境变量中,否则运行的时候提示找不到库

 

4.添加动态库搜索路径   

   (1)export  LD_LIBRARY_PATH=$LD_LIBRAR_PATH:/路径     注意等于号左右2边不要加空格,不然提示找不到路径

        export功能是创建一个新的环境变量

        查看当前的所有环境变量 env

   (2) 打开/etc/ld.so.conf文件, 直接添加你的路径,保存好ldconfig即可.例如:     

         include ld.so.conf.d/*.conf

         /home/ywy/liuzaoxiang/80/videoDownloadSDK/version

5.查看动态库的内容

静态库用ar -t YourFile

动态库用 nm -D YourFile

 

6.动态库静态加载时,在程序运行时被加载进内存,程序退出时才退出内存,多个线程调用时全局变量变量和静态变量公用一块区域, 需要加锁。

动态加载时LoadLibrary加载动态库到内存,FreeLibrary清理内存。

 

7.在linxu下添加新的动态库后,如果无法使用。则运行ldconfig

 

8. windows下库函数重复定义: /FORCE:MULTIPLE


9.   windows静态库可以直接导出类, 动态库导出类需要添加关键字__declspec(dllexport).

      linux动态库和静态库可直接导出类

 #ifdef WIN32
#ifdef MYDLL_EXPORTS
#define MYDLLCLASS   __declspec(dllexport)
#else
#define MYDLLCLASS   __declspec(dllimport)
#endif
#else
#define MYDLLCLASS
#endif

class MYDLLCLASS CTest
{
public:
 CTest();
 ~CTest();
public:
 int Add(int , int);
 int m_iSum;
 virtual void Help();
};

 

10.动态库后面的数字含义

     如libiconv.so.2等,数字一般表示版本号,在使用的时候可以为libiconv.so.2创建一个硬链接libiconv.so,宿主模块直接通过LD_LIBRARY_PATH或其他方法链接到libiconv.so就可以调用libiconv.so.2的库了.如果升级,如有libiconv.so.3,只需要修改链接就可以了。

     关于链接

如果一个文件有链接如libmydll.so则:

ll -i  *.txt

1070305 -rw-r--r-- 3 root root 0 Jan 15 11:09 my.txt   //硬链接 有3个链接
1070305 -rw-r--r-- 3 root root 0 Jan 15 11:09 she.txt
1070304 lrwxrwxrwx 1 root root 6 Jan 15 11:10 you.txt -> my.txt //软链接

通过find / -inum 1070305可以找到所有的链接文件

可以为动态库创建一个硬链接到/usr/lib或者/lib,这样宿主就能直接使用。软链接不可直接使用


11. 动态库中的全局变量问题 (这个是转载的)

       在Win16环境中,DLL的全局数据对每个载入它的进程来说都是相同的,因为所有的进程用的都收同一块地址空间;而在Win32环境中,情况却发生了变化,每个进程都有了它自己的地址空间,DLL函数中的代码所创建的任何对象(包括变量)都归调用它的进程所有。当进程在载入DLL时,操作系统自动把DLL地址映射到该进程的私有空间,也就是进程的虚拟地址空间,而且也复制该DLL的全局数据的一份拷贝到该进程空间。(在物理内存中,多进程载入DLL时,DLL的代码段实际上是只加载了一次,只是将物理地址映射到了各个调用它的进程的虚拟地址空间中,而全局数据会在每个进程都分别加载)。也就是说每个进程所拥有的相同的DLL的全局数据,它们的名称相同,但其值却并不一定是相同的,而且是互不干涉的。

   

在DLL的实现文件中添加下列代码:

#pragma data_seg("DLLSharedSection")      // 声明共享数据段,并命名该数据段
   int SharedData = 50;       // 必须在定义的同时进行初始化!!!!
#pragma data_seg()

 

 在#pragma data_seg("DLLSharedSection")和#pragma data_seg()之间的所有变量将被访问该Dll的所有进程看到和共享。仅定义一个数据段还不能达到共享数据的目的,还要告诉编译器该段的属性,有三种方法可以实现该目的(其效果是相同的),一种方法是在.DEF文件中加入如下语句:

SETCTIONS
    DLLSharedSection READ WRITE SHARED

 

另一种方法是在项目设置的链接选项(Project Setting --〉Link)中加入如下语句:

/SECTION:DLLSharedSection,rws

 

还有一种就是使用指令:

#pragma comment(linker,"/section:.DLLSharedSection,rws")


那么这个数据节中的数据可以在所有DLL的实例之间共享了。所有对这些数据的操作都针对同一个实例的,而不是在每个进程的地址空间中都有一份。
 
当进程隐式或显式调用一个动态库里的函数时,系统都要把这个动态库映射到这个进程的虚拟地址空间里。这使得DLL成为进程的一部分,以这个进程的身份执行,使用这个进程的堆栈。

下面来谈一下在具体使用共享数据段时需要注意的一些问题:

·         所有在共享数据段中的变量,只有在数据段中经过了初始化之后,才会是进程间共享的。如果没有初始化,那么进程间访问该变量则是未定义的。
·         所有的共享变量都要放置在共享数据段中。如何定义很大的数组,那么也会导致很大的DLL。
·         不要在共享数据段中存放进程相关的信息。Win32中大多数的数据结构和值(比如HANDLE)只在特定的进程上下文中才是有效地。
·         每个进程都有它自己的地址空间。因此不要在共享数据段中共享指针,指针指向的地址在不同的地址空间中是不一样的。
·         DLL在每个进程中是被映射在不同的虚拟地址空间中的,因此函数指针也是不安全的。

当然还有其它的方法来进行进程间的数据共享,比如文件内存映射等,这就涉及到通用的进程间通信了,这里就不多讲了。


12.进程调用dll里开辟的内存,属于调用进程内存。


13.g++安装  http://jingyan.baidu.com/article/a3f121e4faf03bfc9052bbeb.html 

 注意: 一定要选择支持的版本

 


0 0
原创粉丝点击