在创建共享库期间的不同情况下,可以使用lib调用哪些函数? [英] In different situations during creating shared libraries, what functions can be called with the lib?
问题描述
我已经阅读了关于共享库和静态库的相关教程,例如:
然而,不幸的是,他们使用的所有示例都是一个函数一个.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 $ c pre
你通常不编译包含
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
andsrc2sh.c
.... Very often, the compilation is driven by a builder program, usually GNU makeFirst, 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 thegcc
flags for debugging purposes. Once your program and shared objects are bug free because you have debugged them withgdb
andvalgrind
, pass-O2
togcc
to have them optimized.Then you need to link all these PIC object files into a single shared object (a
*.so
file), likegcc -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 linkinggcc
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 yourshared.so
You usually don't compile a shared object containing a
main
(remember thatmain
is a very special function, described specifically in the C standard, and called from the startup codecrt*.o
linked bygcc
into every program); this is nearly non-sense (like yourlibexample2.so
). Yourmain
is defined in your program (and you don't need PIC code for your program executable). If your program is made from source filessrc1pr.c
andsrc2pr.c
(which definesmain
) you first compile them asgcc -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 librarylibshared.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 theconstructor
attribute, for a function inside a shared object to be called early at initialization time (if it is a plugin, at itsdlopen
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
togcc
to understand what it is doing...这篇关于在创建共享库期间的不同情况下,可以使用lib调用哪些函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!