C++ 运行时按路径加载共享库

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7626526/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 17:14:49  来源:igfitidea点击:

Load shared library by path at runtime

c++pluginsshared-libraries

提问by aRestless

I am building a Java application that uses a shared library written in C++ and compiled for different operating systems. The problem is, that this shared library itself depends on an additional library it normally finds under the appropriate environment variable (PATH, LIBRARY_PATHor LD_LIBRARY_PATH).

我正在构建一个 Java 应用程序,它使用一个用 C++ 编写并为不同操作系统编译的共享库。问题是,这个共享库本身依赖于它通常在适当的环境变量(PATHLIBRARY_PATHLD_LIBRARY_PATH)下找到的附加库。

I can - but don't want to - set these environment variables. I'd rather load the needed shared libraries from a given path at runtime - just like a plugin. And no - I don't want any starter application that starts a new process with a new environment. Does anybody know how to achieve this?

我可以 - 但不想 - 设置这些环境变量。我宁愿在运行时从给定的路径加载所需的共享库 - 就像插件一样。不 - 我不想要任何启动应用程序在新环境中启动新进程。有谁知道如何实现这一目标?

I know that this must be possible, as one of the libraries I use is capable of loading its plugins from a given path. Of course I'd prefer platform independent code, but if this ain't possible, seperate solutions for Windows, Linux and MacOS would also do it.

我知道这一定是可能的,因为我使用的库之一能够从给定的路径加载其插件。当然,我更喜欢独立于平台的代码,但如果这是不可能的,Windows、Linux 和 MacOS 的单独解决方案也可以做到。

EDITI should have mentioned that the shared library I'd wish to use is object oriented, which means that a binding of single functions won't do it.

编辑我应该提到我希望使用的共享库是面向对象的,这意味着单个函数的绑定不会这样做。

回答by johannes

Un UNIX/Linux systems you can use dlopen. The issue then is you have to fetch all symbols you need via dlsym

您可以使用的 UNIX/Linux 系统dlopen。那么问题是您必须通过以下方式获取您需要的所有符号dlsym

Simple example:

简单的例子:

typedef int (*some_func)(char *param);

void *myso = dlopen("/path/to/my.so", RTLD_NOW);
some_func *func = dlsym(myso, "function_name_to_fetch");
func("foo");
dlclose(myso);

Will load the .so and execute function_name_to_fetch() from in there. See the man page dlopen(1) for more.

将加载 .so 并从那里执行 function_name_to_fetch() 。有关更多信息,请参见手册页 dlopen(1)。

回答by Anteru

On Windows, you can use LoadLibrary, and on Linux, dlopen. The APIs are extremely similar and can load a so/dll directly by providing the full path. That works if it is a run-time dependency (after loading, you "link" by calling GetProcAddress/dlsym.)

在 Windows 上,您可以使用LoadLibrary, 在 Linux 上,您可以使用dlopen. API 非常相似,可以通过提供完整路径直接加载 so/dll。如果它是运行时依赖项(加载后,您可以通过调用GetProcAddress/ 来“链接” dlsym)。

回答by thiton

I concur with the other posters about the use of dlopen and LoadLibrary. The libltdlgives you a platform-independent interface to these functions.

我同意其他关于 dlopen 和 LoadLibrary 使用的海报。该的libltdl为您提供了一个独立于平台的接口,这些功能。

回答by PRouleau

I do not think you can do it for it.

我不认为你可以做到这一点。

Most Dlls have some sort of init() function that must be called after it have been loaded, and sometime that init() function needs some parameters and returns some handle to be used to call the dll's functions. Do you know the definition of the additional library?

大多数 Dll 都有某种 init() 函数,必须在加载后调用,有时该 init() 函数需要一些参数并返回一些句柄以用于调用 dll 的函数。你知道附加库的定义吗?

Then, the first library can not simply look if the DLL X is in RAM only by using its name. The one it needs can be in a different directory or a different build/version. The OS will recognize the library if the full path is the same than another one already loaded and it will share it instead of loading it a second time.

那么,第一个库不能仅仅通过使用其名称来简单地查看DLL X是否在RAM中。它需要的可以在不同的目录或不同的构建/版本中。如果完整路径与另一个已加载的库相同,操作系统将识别该库,并且它将共享它而不是第二次加载它。

The other library can load its plugins from another path because it written to not depend on PATH and they are his own plugins.

另一个库可以从另一个路径加载它的插件,因为它不依赖于 PATH 并且它们是他自己的插件。

Have you try to update the process's environment variables from the code before loading the Dll? That will not depends on a starter process.

您是否尝试在加载 Dll 之前从代码更新进程的环境变量?这不取决于启动过程。