LInux下动态链接库的生成

时间:2022-07-25 15:52:42

参考http://blog.chinaunix.net/uid-20801390-id-3157134.html

首先是动态调用动态库

 

test_so1.h和test_so1.cpp生成test_so1.so动态库。

test_so2.h和test_so2.cpp生成test_so2.so动态库。

test_dll.cpp生成test_dll可执行程序,test_dl通过dlopen系列等API函数,并使用函数指针以到达动态调用不同so库中test函数的目的。

////////////////////////////////test_so1.h//////////////////////////////////////////////////////

#include<iostream>

extern "C" {

int test(void);

}

 

////////////////////////////////test_so1.cpp//////////////////////////////////////////////////////

#include "test_so1.h"

int test(void)

{

        cout<<"USING TEST_SO1.SO NOW!\n"<<endl;//注意此处与test_so2.cpp中的

                                                                        //test函数的不同

return 0;

}

 

//////////////////////////////// test_so2.h //////////////////////////////////////////////////////

#include<iostream>

extern "C" {

int test(void);

}

 

////////////////////////////////test_so2.cpp//////////////////////////////////////////////////////

#include "test_so2.h"

int test(void)

{

        cout<<"USING TEST_SO2.SO NOW!\n"<<endl;//注意此处与test_so1.cpp中的

                                                                        //test函数的不同

        return 0;

}

 

////////////////////////////////test_dll.cpp//////////////////////////////////////////////////////

#include<iostream>

#include<dlfcn.h>

#include<stdio.h>

#include<stdlib.h>

 

int main(int argc, char **argv)

{

        if(argc!=2)

        {

                cout<<"Argument Error! You must enter like this:"<<endl;

                cout<<"./test_dl test_so1.so"endl;

                exit(1);

        }

 

        void *handle;

        char *error;

        typedef void (*pf_t)();   //声明函数指针类型

 

        handle = dlopen (argv[1], RTLD_NOW);     //打开argv[1]指定的动态库

 

        if (!handle)

        {

                fprintf (stderr, "%s\n", dlerror());

                exit(1);

        }

 

        dlerror();   

         pf_t pf=(pf_t)dlsym(handle,"test" );    //指针pf指向test在当前内存中的地址

        if ((error = dlerror()) != NULL) 

        {

                fprintf (stderr, "%s\n", error);

                exit(1);

        }

        pf();        //通过指针pf的调用来调用动态库中的test函数

        dlclose(handle);      //关闭调用动态库句柄

        return 0;

}


//然后下面是参考的文章中的Makefile

////////////////////////////////makefile//////////////////////////////////////////////////////

.SUFFIXES: .c .cpp .o

CC=g++  -shared -fPIC

GCC=g++

 

all:test_so1.so test_so2.so test_dll clean

 

OBJ1=test_so1.o

OBJ2=test_so2.o

OBJ3=test_dll.o

 

test_so1.so:$(OBJ1)

        $(CC) -o $@ $?

        cp $@ /usr/lib

 

test_so2.so:$(OBJ2)

        $(CC) -o $@ $?

        cp $@ /usr/lib

 

test_dll:$(OBJ3)

        $(GCC)  -o $@ $? -ldl

 

.cpp.o:

        $(CC) -c $*.cpp

.c.o:

        $(CC) -c $*.c

clean:

        rm -f *.o

在终端中的当前指令下执行make是,生成了test_so1.so和test_so2.so的动态库文件,但是还会出现下面的错误。


huangbo@huangbo:~/test4$ sudo make
g++  -shared -fPIC -c test_so2.cpp
g++  -shared -fPIC -o test_so2.so test_so2.o
cp test_so2.so /usr/lib
g++     test_dll.cpp   -o test_dll
/tmp/cc1ywB9U.o:在函数‘main’中:
test_dll.cpp:(.text+0x6b):对‘dlopen’未定义的引用
test_dll.cpp:(.text+0x7b):对‘dlerror’未定义的引用
test_dll.cpp:(.text+0xa6):对‘dlerror’未定义的引用
test_dll.cpp:(.text+0xb7):对‘dlsym’未定义的引用
test_dll.cpp:(.text+0xc0):对‘dlerror’未定义的引用
test_dll.cpp:(.text+0x109):对‘dlclose’未定义的引用
collect2: error: ld returned 1 exit status
make: *** [test_dll] 错误 1

由于自己是菜鸟,还不知道是什么原因引起的。经查资料发现。如果执行

huangbo@huangbo:~/test4$ g++ test_dll.cpp -ldl -o test_dll

则可以生成test_dll的动态库。

然后则可以正常运行                                                                 

huangbo@huangbo:~/test4$ ./test_dll test_so1.so
USING TEST_SO1.SO NOW!
huangbo@huangbo:~/test4$ ./test_dll test_so2.so
USING TEST_SO2.SO NOW!
huangbo@huangbo:~/test4$ ./test_dll
Argument Error! You must enter like this:
./test_dl test_so1.so

参考的文章是http://www.linuxdiyf.com/linux/16754.html。原因可以看这篇文章  ////////ps:上面的Makefile可以正常生成可执行文件,是我弄错了导致出现问题!!