全球彩票平台_全球彩票注册平台|官网下载地址

热门关键词: 全球彩票平台,全球彩票注册平台,全球彩官网下载地址

全球彩票注册平台Linux下动态链接库的使用,Li

如何用c语言调用c 做成的动态链接库,动态链接库

今天在做东西的时候遇到一个问题,就是如何在C语言中调用C 做的动态链接库so文件
如果你有一个c 做的动态链接库.so文件,而你只有一些相关类的声明, 那么你如何用c调用呢,别着急,本文通过一个小小的例子,让你能够很爽的搞定.   
链接库头文件:
head.h

class A  
{  
        public:  
        A();  
        virtual ~A();  
        int gt();  
        int pt();  
private:  
        int s;  
};  
// 何问起 hovertree.com

firstso.cpp

#include <iostream>   
#include "head.h"  


A::A(){}  
A::~A(){}  
int A::gt()  
{  
    s=10;  
}  
int A::pt()  
{  
        std::cout<<s<<std::endl;  
}  
// 何问起 hovertree.com

编译命令如下:
g -shared -o libmy.so firstso.cpp
这时候生成libmy.so文件,将其拷贝到系统库里面:/usr/lib/
进行二次封装:

secso.cpp

#include <iostream>  
#include "head.h"  
extern "C"  
{  
int f();  
int f()  
{  
A a;  
a.gt();  
a.pt();  
return 0;  
}  
}  
// 何问起 hovertree.com

编译命令:
gcc -shared -o sec.so secso.cpp -L. -lmy
这时候生成第二个.so文件,此时库从一个类变成了一个c的接口.
拷贝到/usr/lib
下面开始调用:
test.c

#include "stdio.h"  
#include "dlfcn.h"  


#define SOFILE "sec.so"  
int (*f)();  
int main()  
{  
void *dp;  
dp=dlopen(SOFILE,RTLD_LAZY);  
f=dlsym(dp,"f");  
f();  
return 0;  
}  
// 何问起 hovertree.com

编译命令如下:
gcc -rdynamic -s -o myapp test.c

 

运行Z$./myapp

10
$

 

今天在做东西的时候遇到一个问题,就是如何在C语言中调用C 做的动态链接库so文件 如...

今天在做东西的时候遇到一个问题,就是如何在C语言中调用C 做的动态链接库so文件
如果你有一个c 做的动态链接库.so文件,而你只有一些相关类的声明, 那么你如何用c调用呢,别着急,本文通过一个小小的例子,让你能够很爽的搞定.   
链接库头文件:
head.h

   以下实例的环境是amd64 ubuntu10.10 g 4.4.5测试成功,在其他配置的机器上可能有一点区别。

Linux动态链接和静态链接简析

Linux下的静态链接库,做起来比较容易,只要将目标文件用ar打包就可以,下面写一下动态链接库的制作和使用方法,完全是根据个人理解和经验总结,有不对的地方还请大家指正。

class A  
{  
        public:  
        A();  
        virtual ~A();  
        int gt();  
        int pt();  
private:  
        int s;  
};  
// 何问起 hovertree.com

    动态库的使用方式中有两种,第一种是类似于静态库的使用,另一种我称之为真正的动态加载动态库,主要是因为这种方式在程序运行的过程中加载链接库,使用之后在卸载链接库。

 

动态链接库的生成:

firstso.cpp

    先介绍第一种。

1.生成静态链接库

代码上与写静态链接库没什么区别,主要是在编译时,以两个文件举例:

#include <iostream>   
#include "head.h"  


A::A(){}  
A::~A(){}  
int A::gt()  
{  
    s=10;  
}  
int A::pt()  
{  
        std::cout<<s<<std::endl;  
}  
// 何问起 hovertree.com

    在目录/home/owner/test/下创建我们的实验程序:

 gcc -c h.c -o h.o

全球彩票注册平台 1

编译命令如下:
g -shared -o libmy.so firstso.cpp
这时候生成libmy.so文件,将其拷贝到系统库里面:/usr/lib/
进行二次封装:

        //dll_fun.c

 ar cqs libh.a h.o 

/*mylib.h*/
void Print();

secso.cpp

        #include <stdio.h>

 //ar是生成库的命令,cqs是参数,libh.a是生成的静态链接库须以lib开头,h是库名,a表示是静态链接库,h.o是刚才生成目标文件

/*mylib.c*/
#include <stdio.h>
#include "mylib.h"

#include <iostream>  
#include "head.h"  
extern "C"  
{  
int f();  
int f()  
{  
A a;  
a.gt();  
a.pt();  
return 0;  
}  
}  
// 何问起 hovertree.com

        void dll_function(const char* szString)

2.生成动态链接库  www.2cto.com  

void Print()
{
    printf("This is in mylibn");
}

编译命令:
gcc -shared -o sec.so secso.cpp -L. -lmy
这时候生成第二个.so文件,此时库从一个类变成了一个c的接口.
拷贝到/usr/lib
下面开始调用:
test.c

        {

 gcc -c h.c -o h.o

全球彩票注册平台 2

#include "stdio.h"  
#include "dlfcn.h"  


#define SOFILE "sec.so"  
int (*f)();  
int main()  
{  
void *dp;  
dp=dlopen(SOFILE,RTLD_LAZY);  
f=dlsym(dp,"f");  
f();  
return 0;  
}  
// 何问起 hovertree.com

                printf("%sn", szString);

 生成动态链接库用gcc来完成

编译方法如下:

编译命令如下:
gcc -rdynamic -s -o myapp test.c

        }

 gcc -shared -WI -o libh.so h.o

gcc -fpic -shared mylib.c -o mylib.so

 

    编译生成动态链接库

 //-shared -WI是参数,libh.so是生成的静态链接库须以lib开头,h是库名,so表示是动态链接库,h.o是刚才生成目标文件

此时将生成mylib.so动态链接库文件。

运行Z$./myapp

        gcc -c -fPIC dll_fun.c //这里一定要加上-fPIC选项,不然下一步编译失败

3.将生成的libh.a,libh.so拷贝到/usr/lib或/lib下

动态链接库在使用时,分为“隐式调用”和“显式调用”两种,如果是隐式调用,则与静态库的使用方法差不多,注意需要包含导出函数的头文件,即mylib.h:

10
$

        gcc -shared -fPIC -o libdllfun.so dll_fun.o //生成动态链接库libdllfun.so

4.编译带静态链接库的程序

全球彩票注册平台 3

 

    创建调用动态库方法:

 gcc -c test.c -o test.o

#include <stdio.h>
#include "mylib.h"

        //main.c

 gcc test.o -o test -WI -Bstatic -lh

int main()
{
    Print();
}

        void dll_function(const char* szString);

 //-WI -Bstatic表示链接静态库,-lh中-l表示链接,h是库名即/usr/lib下的libh.a

全球彩票注册平台 4

        int main()

5.编译带动态链接库的程序

编译方法:

        {

 gcc -c test.c -o test.o

gcc -o main main.c -L./ mylib.so

               dll_function("This is the words of the dll function!!!!!!");

 gcc test.o -o test -WI -Bdynamic -lh

注意要加上动态链接库的搜索路径,否则编译器只会到系统路径中去寻找。

               return 0; 

 //-WI -Bdynamic表示链接动态库,-lh中-l表示链接,h是库名即/usr/lib下的libh.so

显式调用的方式,不必包含mylib.h,但是需要增加几个系统调用:

        }

6.运行./test得到结果  www.2cto.com  

全球彩票注册平台 5

    编译main.c生成可执行文件

7.其他知识

#include <stdio.h>
#include <dlfcn.h> // 显式加载需要用到的头文件

        gcc -o main main.c -L. -ldllfun //这里提供了刚才生成的dllfun库

 有些库形如libh.so.1.0,1.0表示版本号.若要使用该库,通常要建立一个软连接,用ln -s libh.so.1.0 libh.so.系统不知道1.0为何意思。

int  main()
{
    void *pdlHandle = dlopen("./mylib.so", RTLD_LAZY); // RTLD_LAZY 延迟加载
    char *pszErr = dlerror();
    if( !pdlHandle || pszErr )
    {
        printf("Load mylib failed!n")
        return 1;
    }

    如果此时执行./main的话,会出现如下错误:

 编译连接时同时要用动态和静态链接库,则用如下命令

    void (*Print)() = dlsym(pdlHandle, "Print"); // 定位动态链接库中的函数
    if( !Print )
    {
        pszErr = dlerror();
        printf("Find symbol failed!%sn", pszErr);
        dlclose(pdlHandle);
        return 1;
    }

        cannot open shared object file: No such file or directory

 gcc test.o -o test -WI -Bstatic -lh1 -WI -Bdynamic -lh2

    Print(); // 调用动态链接库中的函数

    这是因为系统未找到动态库libdllfun.so。

 

    dlclose(pdlHandle); // 系统动态链接库引用数减1

    Linux动态链接库的默认搜索路径是/lib和/usr/lib,因此动态库被创建后,一般都复制到这两个目录下面,当程序执行时需要某动态库,并且改动态库还没有加载到内存中,则系统会自动到这两个默认的搜索路径中去查找相应的动态库文件,然后加载改文件到内存中,这样程序就可以使用该动态库中的函数以及该动态库中的其他资源了。在linux中,动态库的搜索路径除了默认的搜索路径外,还可以通过其他三种方法来指定,这里只介绍其中的一种:通过环境变量LD_LIBRARY_PATH指定动态库搜索路径。

8.动态库和静态库的位置问题

    return 0;
}

    当通过该环境变量指定多个动态链接库搜索路径时,路径之间用冒号":"分隔。     

 

全球彩票注册平台 6

    使用下面命令来配置环境

 把动态库或者静态库放在/usr/lib或者/lib下,在链接的时候系统会自动到这两个目录下寻找。如果没有放在这两个目录下,则修改/etc/ld.so.conf文件,把目录写入该文件,然后ldconfig,就OK了。

 

      mkdir /home/owner/test/lib//将这个目录设置为动态库的存放目录

 

可以看到,显式调用的代码看上去要复杂很多,但是却比隐式调用要灵活,我们不必在编译时就确定要加载哪个动态链接库,可以在运行时再确定,甚至重新加载。

       mkdir/home/owner/test/libdllfun.so /home/owner/test/lib/libdllfun.so

 如果没有放在usr/lib或者/lib目录下,也不修改/etc/ld.so.conf文件,也可以在编译的时候加上 -L/路径 也可以。但是在执行的时候还是会提示找不到库的所在。

看一下显式调用的编译方式:

       export LD_LIBRARY_PATH=/home/owner/test/lib

 

gcc -ldl -o main main.c

   此时设置这个环境变量之后的所有命令命令中,该环境变量都有效。

 

注意要添加-ldl选项,以使用显式调用相关的函数调用。

       ./main

作者 llg521208

 

   可得如下结果:

1.生成静态链接库 gcc -c h.c -o h.o ar cqs libh.a h.o //ar是生成库的命令,cqs是参数,libh.a是生成的静态链接库须以l...

/****************************************************这是一条分割线************************************/

       This is the words of the dll function!!!!!!

 

 第二种加载动态库实例:

2.2  动态调用,使用dl系列函数,完成对动态库函数的调用。

       //dll_fun.c

2.2.1 重要的dlfcn.h头文件
    LINUX下使用动态链接库,源程序需要包含dlfcn.h头文件,此文件定义了调用动态链接库的函数的原型。

       #include<stdio.h>

2.2.2 dlerror
    原型为: const char *dlerror(void);
    当动态链接库操作函数执行失败时,dlerror可以返回出错信息,返回值为NULL时表示操作函数执行成功。

        void dll_function(const char* szString)

2.2.3 dlopen
    原型为: void *dlopen (const char *filename, int flag);
    dlopen用于打开指定名字(filename)的动态链接库,并返回操作句柄。
filename: 如果名字不以/开头,则非绝对路径名,将按下列先后顺序查找该文件。
    (1) 用户环境变量中的LD_LIBRARY_PATH值;
    (2) 动态链接缓冲文件/etc/ld.so.cache
    (3) 目录/lib,/usr/lib
flag表示在什么时候解决未定义的符号(调用)。取值有两个:
    1) RTLD_LAZY : 表明在动态链接库的函数代码执行时解决。
    2) RTLD_NOW : 表明在dlopen返回前就解决所有未定义的符号,一旦未解决,dlopen将返回错误。
    dlopen调用失败时,将返回NULL值,否则返回的是操作句柄。

       {

2.2.4 dlsym : 取函数执行地址
    原型为: void *dlsym(void *handle, char *symbol);
    dlsym根据动态链接库操作句柄(handle)与符号(symbol),返回符号对应的函数的执行代码地址。由此地址,可以带参数执行相应的函数。
如程序代码: void (*print_func)(char *buf); /* 说明一下要调用的动态函数print_func*/
    print_func=dlsym("libfunc.so","print"); /* 打开libfunc.so共享库,取print函数地址 */
    print_func("John"); /* 调用print_func函数 */

本文由全球彩票平台发布于全球彩票注册平台编程,转载请注明出处:全球彩票注册平台Linux下动态链接库的使用,Li

TAG标签: 全球彩票平台
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。