在创建共享库期间的不同情况下,可以使用lib调用哪些函数? [英] In different situations during creating shared libraries, what functions can be called with the lib?

查看:88
本文介绍了在创建共享库期间的不同情况下,可以使用lib调用哪些函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了关于共享库和静态库的相关教程,例如:

使用gnu编译器[gcc]创建共享库和静态库



静态,共享动态和可加载的Linux库



然而,不幸的是,他们使用的所有示例都是一个函数一个.c文件。



我有两个问题:

(1)如果我有一个包含两个函数的文件,例如example1.c

  void ctest11 (int * i)
{* i = 5; }

void ctest12(int * i)
{* i = 5; }

将exmaple1.c编译为libexample1.so后,我可以调用ctest11和ctest12吗?

(2)如果我有一个文件带有两个以上的函数,其中一个是主函数,比如example2.c

  void ctest21(int * i)
{* i = 5; }

void main(int * i)
{* i = 5; }

将exmaple2.c编译为libexample2.so后,是否与编译一个.c相同(3)如果我有一个文件example3.c和exmaple4.c
example3.c中的函数将使用函数in example4.c
例如:
example3.c

  void ctest31(int * i)
{* i = ctest41(2,3); }

example4.c

  int ctest41(int a,int b)
{return a + b; }

当我编译example2.c和example3.c到libexample23.so时,我可以同时调用ctest31和ctest41?

但是如果gcc example2.c example3.o到libexample2.so,我猜我只能调用ctest31?


$ b解决方案

$ b

通常,共享对象可以由几个C源文件 src1sh.c src2sh.c ....很多时候,编译是由构建器程序驱动的,通常是 GNU make rel =nofollow>位置无关代码(PIC)eg

  gcc -Wall -fPIC src1sh .c -c -o src1sh.pic.o 
gcc -Wall -fPIC src2sh。 c -c -o src2sh.pic.o

您可能想要添加 -g 添加到 gcc 标志以进行调试。一旦你的程序和共享对象无错误,因为你已经用 gdb valgrind 进行了调试,通过 -O2 转换为 gcc 来优化它们。



然后,您需要将所有这些PIC目标文件链接到一个共享对象( *。so 文件),如

  gcc -shared src1sh.pic.o src2sh.pic.o -o shared.so 

如果你的目的是让一个共享库调用它 lib * .so eg libfoo.so 并将其引用为 -lfoo 标志到链接 gcc 命令使用你的共享库。



注意,链接一个共享对象也可以链接其他共享库,所以你可以这样做:

  gcc -shared src1sh.pic.o src2sh.pic.o -lsome -o shared.so 
libsome.so 链接到您的 shared.so

你通常不编译包含 main 的共享对象(请记住 main 是一个非常特殊的函数,具体在 C 标准中描述,并从启动代码 crt * .o 通过 gcc 链接到每个程序中);这几乎是无意义的(就像你的 libexample2.so )。您的程序中定义了您的 main (并且您的程序可执行文件不需要PIC代码)。如果你的程序是由源文件 src1pr.c src2pr.c (它定义您首先将它们编译为

  gcc -Wall src1pr.c -c -o src1pr。 o 
gcc -Wall src2pr.c -c -o src2pr.o

和您的链接他们都有例如

  gcc src1pr.o src2pr.o -o prog -lshared 

其中 -lshared 引用共享库 libshared.so (你可能想要编译你的程序文件并用 -g 链接你的程序文件以获得调试信息,你可能想要传递额外的 -I 标志用于包含目录, -L 用于库目录的标志,例如 -L。在当前目录中搜索库...)



有一种方法可以动态链接到运行时某个共享对象,特别是有插件。然后,您需要使用 dlopen & dlsym functons(你通常希望链接你的主程序和 -rdynamic 标志)。



您可以从共享对象中调用(从您的程序)任何可见功能。你可能想要玩知名度 功能属性例如限制共享对象内某些函数的可见性。对于共享对象内的一个函数,可能需要稍后使用构造函数属性,以便在初始化时尽早调用该函数(如果它是插件,则它的 dlopen time)。



阅读程序库Howto Levine的Linkers and Loaders书籍了解更多。 Linux共享对象(以及可重定位对象 *。o 和可执行二进制文件)位于可执行文件&可链接格式(ELF是行业标准)。一些进一步的细节在应用程序二进制接口中描述(特别是针对您的处理器的ABI补充,例如 AMD64 ABI补充)。

PS。您真的希望像GNU make 这样的构建器合并所有这些步骤,因此请阅读其文档。您可能希望将 -v 传递给 gcc 以了解它在做什么...


I have read related tutorials regarding shared and static libraries, such as:

"Creating a shared and static library with the gnu compiler [gcc]"

"Static, Shared Dynamic and Loadable Linux Libraries"

However, unfortunately, all examples they used are one function one .c file.

I have two questions:

(1) If I have one file with two more functions, such as example1.c

void ctest11(int *i)
{ *i = 5; }

void ctest12(int *i)
{ *i = 5; }

After compiling exmaple1.c to libexample1.so, can I call ctest11 and ctest12 in it?

(2) If I have one file with two more functions, one of them is a main function, such as example2.c

void ctest21(int *i)
{ *i = 5; }

void main(int *i)
{ *i = 5; }

After compiling exmaple2.c to libexample2.so, is it the same as to compile one .c file with only ctest21 function?

(3) If I have one file example3.c and exmaple4.c The funcion in example3.c will use the function in example4.c For example: example3.c

void ctest31(int *i)
{ *i = ctest41(2,3); }

example4.c

int ctest41(int a, int b)
{ return a+b; }

When I compile example2.c and example3.c to libexample23.so, can I call both ctest31 and ctest41?

But if gcc example2.c example3.o to libexample2.so, I guess I can only call ctest31?

解决方案

You should look inside (and build) some existing free software library, compile it, and study its code and building process.

In general, a shared object can be made from several C source files src1sh.c and src2sh.c .... Very often, the compilation is driven by a builder program, usually GNU make

First, you need to compile every source file of the shared object as position-independent-code (PIC) e.g.

gcc -Wall -fPIC src1sh.c -c -o src1sh.pic.o
gcc -Wall -fPIC src2sh.c -c -o src2sh.pic.o

You probably want to add -g to the gcc flags for debugging purposes. Once your program and shared objects are bug free because you have debugged them with gdb and valgrind, pass -O2 to gcc to have them optimized.

Then you need to link all these PIC object files into a single shared object (a *.so file), like

gcc -shared src1sh.pic.o src2sh.pic.o -o shared.so

If your intent is to make a shared library call it lib*.so e.g. libfoo.so and refer to it as -lfoo flag to the linking gcc command using your shared library.

Notice that linking a shared object may also link other shared libraries, so you could do

gcc -shared src1sh.pic.o src2sh.pic.o -lsome -o shared.so

to link some libsome.so into your shared.so

You usually don't compile a shared object containing a main (remember that main is a very special function, described specifically in the C standard, and called from the startup code crt*.o linked by gcc into every program); this is nearly non-sense (like your libexample2.so). Your main is defined in your program (and you don't need PIC code for your program executable). If your program is made from source files src1pr.c and src2pr.c (which defines main) you first compile them as

gcc -Wall src1pr.c -c -o src1pr.o
gcc -Wall src2pr.c -c -o src2pr.o

and you link them all with e.g.

gcc src1pr.o src2pr.o -o prog -lshared

where -lshared refers to a shared library libshared.so (you probably want to compile and link your program files with -g for debugging information, and you may want to pass additional -I flags for include directories, and -L flags for library directories, e.g. -L. to search library in the current directory ...)

There is a way to dynamically link at runtime some shared object, notably for having plugins. You then want to use the dlopen & dlsym functons for that (and you usually want to link your main program with -rdynamic flag).

You can call (from your program) any visible function inside a shared object. You may want to play with the visibility function attribute to e.g. restrict the visibility of some function inside your shared object. You might perhaps want to later use the constructor attribute, for a function inside a shared object to be called early at initialization time (if it is a plugin, at its dlopen time).

Read Program Library Howto and Levine's "Linkers and Loaders" book for more. Linux shared objects (and relocatable object *.o, and executable binaries) are in Executable & Linkable Format (ELF is an industry standard). Some further details are described in the Application Binary Interface (and notably the ABI supplement for your processor, e.g. AMD64 ABI supplement).

PS. You really want a builder like GNU make to combine all these steps, so read its documentation. You might want to pass -v to gcc to understand what it is doing...

这篇关于在创建共享库期间的不同情况下,可以使用lib调用哪些函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆