共享库和 .h 文件

发布于 2024-07-27 23:15:53 字数 334 浏览 14 评论 0原文

我对程序如何使用共享库有一些疑问。

当我构建共享库(使用 -shared -fPIC 开关)时,我可以从外部程序使用一些函数。 通常我会使用 dlopen() 来加载库,然后使用 dlsym() 将上述函数链接到程序中的某些函数指针。 此方法不涉及包含任何 .h 文件。 有没有办法避免执行 dlopen() & dlsym() 并且只包含共享库的 .h

我猜这可能是 C++ 程序如何使用存储在系统共享库中的代码,即 - 仅包括 stdlib.h 等。

I have some doubt about how do programs use shared library.

When I build a shared library ( with -shared -fPIC switches) I make some functions available from an external program.
Usually I do a dlopen() to load the library and then dlsym() to link the said functions to some function pointers within my program.
This approach does not involve including any .h file.
Is there a way to avoid doing dlopen() & dlsym() and just including the .h of the shared library?

I guess this may be how C++ programs use code stored in system shared library, i.e - just including stdlib.h etc.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

究竟谁懂我的在乎 2024-08-03 23:16:02
  • 共享库 (.so) 是目标文件,其中存储函数/类/...的实际源代码(以二进制形式)
  • 头文件 (.h) 是文件指示(引用)编译器可以在哪里找到主代码所需的函数/类/...(在 .so 中)

因此,您需要它们。

  • Shared libraries (.so) are object files where the actual source code of function/class/... are stored (in binary)
  • Header files (.h) are files indicating (the reference) where the compiler can find function/class/... (in .so) that are required by the main code

Therefore, you need both of them.

往事风中埋 2024-08-03 23:16:01

如果您使用 CMake 构建项目,则可以使用

TARGET_LINK_LIBRARIES(targetname libraryname)

如下所示:

TARGET_LINK_LIBRARIES(myprogram mylibrary)

要创建库“mylibrary”,您可以使用

ADD_LIBRARY(targetname sourceslist)

As:

ADD_LIBRARY(mylibrary ${mylibrary_SRCS})

此外,此方法是跨平台的(而简单地将标志传递给 gcc 则不是)。

If you use CMake to build your project, you can use

TARGET_LINK_LIBRARIES(targetname libraryname)

As in:

TARGET_LINK_LIBRARIES(myprogram mylibrary)

To create the library "mylibrary", you can use

ADD_LIBRARY(targetname sourceslist)

As in:

ADD_LIBRARY(mylibrary ${mylibrary_SRCS})

Additionally, this method is cross-platform (whereas simply passing flags to gcc is not).

卖梦商人 2024-08-03 23:16:00

您需要向链接器提供正确的指令来链接您的共享库。

共享库名称类似于 libNAME.so,因此为了链接,您应该使用 -lNAME

将其命名为 libmysharedlib.so,然后将主程序链接为:

gcc -o myprogram myprogram.c -lmysharedlib 

You need to give the linker the proper instructions to link your shared library.

The shared library names are like libNAME.so, so for linking you should use -lNAME

Call it libmysharedlib.so and then link your main program as:

gcc -o myprogram myprogram.c -lmysharedlib 
心房的律动 2024-08-03 23:15:58

您可以像静态库一样链接共享库。 然后在启动程序时搜索它们。 事实上,默认情况下 -lXXX 会优先选择 libXXX.so 而不是 libXXX.a。

You can link shared libraries like static one. They are then searched for when launching the program. As a matter of fact, by default -lXXX will prefer libXXX.so to libXXX.a.

叹倦 2024-08-03 23:15:57

尼克,我认为所有其他答案实际上都在回答您的问题,这就是您链接库的方式,但是您表达问题的方式表明您对头文件和库之间的差异存在误解。 他们不一样。 你需要两者,但他们做的不是同一件事。

构建可执行文件有两个主要阶段:编译(将源代码转换为中间形式,包含可执行二进制指令,但不是可运行的程序)和链接(将这些中间文件组合成单个运行的可执行文件或库)。

当您执行gcc -c program.c时,您正在编译,并生成program.o。 这一步是标题最重要的地方。 您需要在 program.c 中添加 #include 才能(例如)使用 mallocfree. (同样,对于 dlopendlsym,您需要 #include。)如果您不这样做,编译器会抱怨它不知道这些名称是什么,并因错误而停止。 但是,如果您#include标头,编译器不会将您调用的函数的代码插入到program.o中。 它只是插入对它们的引用。 原因是为了避免代码重复:程序的每个部分只需要访问代码一次,因此如果您需要更多文件(module1.cmodule2.c), c 等),即使它们全部使用了 malloc,您最终也只会得到对 malloc 单个副本的许多引用>。 该单个副本以共享或静态形式(libc.solibc.a)存在于标准中,但这些不是在您的源代码中引用,并且编译器不知道它们。

链接器。 在链接阶段,您执行gcc -o program program.o。 然后,链接器将搜索您在命令行上传递给它的所有库,并找到您调用的所有函数的单个定义,这些函数未在您自己的代码中定义。 这就是 -l 的作用(正如其他人所解释的):告诉链接器您需要使用的库列表。 它们的名称通常与您在上一步中使用的标头关系不大。 例如,要使用dlsym,您需要libdl.solibdl.a,因此您的命令行将是gcc - o 程序program.o -ldl。 要使用 mallocstd*.h 标头中的大多数函数,您需要 libc,但因为该库由 使用每个 C 程序都会自动链接(就好像您已经完成了-lc)。

抱歉,如果我要讲很多细节,但如果您不知道其中的区别,您会想要了解的。 如果不这样做,就很难理解 C 编译的工作原理。

最后一件事:dlopendlsym 不是正常的链接方法。 它们用于特殊情况,在这种情况下,您希望根据无论出于何种原因仅在运行时可用的信息动态确定所需的行为。 如果您知道要在编译时调用哪些函数(99% 的情况下都是如此),则不需要使用 dl* 函数。

Nick, I think all the other answers are actually answering your question, which is how you link libraries, but the way you phrase your question suggests you have a misunderstanding of the difference between headers files and libraries. They are not the same. You need both, and they are not doing the same thing.

Building an executable has two main phases, compilation (which turns your source into an intermediate form, containing executable binary instructions, but is not a runnable program), and linking (which combines these intermediate files into a single running executable or library).

When you do gcc -c program.c, you are compiling, and you generate program.o. This step is where headers matter. You need to #include <stdlib.h> in program.c to (for example) use malloc and free. (Similarly you need #include <dlfcn.h> for dlopen and dlsym.) If you don't do that the compiler will complain that it doesn't know what those names are, and halt with an error. But if you do #include the header the compiler does not insert the code for the function you call into program.o. It merely inserts a reference to them. The reason is to avoid duplication of code: The code is only going to need to be accessed once by every part of your program, so if you needed further files (module1.c, module2.c and so on), even if they all used malloc you would merely end up with many references to a single copy of malloc. That single copy is present in the standard library in either it's shared or static form (libc.so or libc.a) but these are not referenced in your source, and the compiler is not aware of them.

The linker is. In the linking phase you do gcc -o program program.o. The linker will then search all libraries you pass it on the command line and find the single definition of all functions you've called which are not defined in your own code. That is what the -l does (as the others have explained): tell the linker the list of libraries you need to use. Their names often have little to do with the headers you used in the previous step. For example to get use of dlsym you need libdl.so or libdl.a, so your command-line would be gcc -o program program.o -ldl. To use malloc or most of the functions in the std*.h headers you need libc, but because that library is used by every C program it is automatically linked (as if you had done -lc).

Sorry if I'm going into a lot of detail but if you don't know the difference you will want to. It's very hard to make sense of how C compilation works if you don't.

One last thing: dlopen and dlsym are not the normal method of linking. They are used for special cases where you want to dynamically determine what behavior you want based on information that is, for whatever reason, only available at runtime. If you know what functions you want to call at compile time (true in 99% of the cases) you do not need to use the dl* functions.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文