本地动态库(Local dynamic library)

马上,我想说我从未使用过动态库,所以我甚至不知道它们是如何正常工作的。

我希望运行一个完全加载的代码,并在一些触发器(可能是用户交互)之后,我想加载一个特定的库并在该库中执行一个函数。 最好在之后关闭它。 基本上允许我在运行时更改它并重新加载它。

这是一个简单的动态库(名为dynlib.so,位于与主代码相同的目录中):

int getInt(int arg_0) { return (arg_0 + 7); }

这是主要计划:

#include <iostream> #include <dlfcn.h> int main() { void *lib_handle = dlopen("./dynlib.so", RTLD_LAZY | RTLD_NOW); if (!lib_handle) { fprintf(stderr, "%s\n", dlerror()); exit(EXIT_FAILURE); } typedef int (*func_ptr)(int); func_ptr func = (func_ptr)dlsym(lib_handle, "getInt"); std::cout << func(13); dlclose(lib_handle); }

我正在使用它编译它: g ++ -std = c ++ 11 -ldl loadlibtest.cpp -o main

我抓到的错误是./libshared.so:文件太短在我的if (!lib_handle) { 。

Right off the bat, I want to say that I've never worked with dynamic libraries so It's possible that I don't even understand how they work properly.

I want to have a fully loaded code running and after some trigger (probably user interaction) I want to load a specific library and execute a function inside that library. Preferably close it afterwards. Essentially allowing me to change it and re-load it during run time.

This is the simple dynamic library (called dynlib.so located in the same directory as the main code):

int getInt(int arg_0) { return (arg_0 + 7); }

And this is the main program:

#include <iostream> #include <dlfcn.h> int main() { void *lib_handle = dlopen("./dynlib.so", RTLD_LAZY | RTLD_NOW); if (!lib_handle) { fprintf(stderr, "%s\n", dlerror()); exit(EXIT_FAILURE); } typedef int (*func_ptr)(int); func_ptr func = (func_ptr)dlsym(lib_handle, "getInt"); std::cout << func(13); dlclose(lib_handle); }

I'm compiling it using: g++ -std=c++11 -ldl loadlibtest.cpp -o main.

The error I'm catching is ./libshared.so: file too short In my if (!lib_handle) {.

最满意答案

这对我来说可以。 我编译了dynlib.so

$ gcc dynlib.c -fPIC -shared -o dynlib.so

(显然,您需要将其编译为带有extern "C" C或C ++以避免名称损坏)。

我需要在g++调用中将-ldl放在源文件之后。

gcc:4.8.5; g ++:5.3.0


dlsym也可能失败,从void *到函数指针的转换在技术上是UB。 您应该将其基于联机帮助页中的用法代码段 (针对您的函数进行了修改):

dlerror(); /* Clear any existing error */ /* Writing: func = (int (*)(int)) dlsym(handle, "getInt"); would seem more natural, but the C99 standard leaves casting from "void *" to a function pointer undefined. The assignment used below is the POSIX.1-2003 (Technical Corrigendum 1) workaround; see the Rationale for the POSIX specification of dlsym(). */ *(void **) (&func) = dlsym(handle, "getInt"); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); exit(EXIT_FAILURE); }

It works fine for me. I've compiled dynlib.so with

$ gcc dynlib.c -fPIC -shared -o dynlib.so

(Obviously, you need to either compile it as C or C++ with extern "C" to avoid name mangling).

and I needed to place -ldl after the source file in the g++ invocation.

gcc: 4.8.5; g++: 5.3.0


dlsym may fail too and casting from void* to function pointers is technically UB. You should base it on the usage snippet from the manpage(modified for your function):

dlerror(); /* Clear any existing error */ /* Writing: func = (int (*)(int)) dlsym(handle, "getInt"); would seem more natural, but the C99 standard leaves casting from "void *" to a function pointer undefined. The assignment used below is the POSIX.1-2003 (Technical Corrigendum 1) workaround; see the Rationale for the POSIX specification of dlsym(). */ *(void **) (&func) = dlsym(handle, "getInt"); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); exit(EXIT_FAILURE); }本地动态库(Local dynamic library)

马上,我想说我从未使用过动态库,所以我甚至不知道它们是如何正常工作的。

我希望运行一个完全加载的代码,并在一些触发器(可能是用户交互)之后,我想加载一个特定的库并在该库中执行一个函数。 最好在之后关闭它。 基本上允许我在运行时更改它并重新加载它。

这是一个简单的动态库(名为dynlib.so,位于与主代码相同的目录中):

int getInt(int arg_0) { return (arg_0 + 7); }

这是主要计划:

#include <iostream> #include <dlfcn.h> int main() { void *lib_handle = dlopen("./dynlib.so", RTLD_LAZY | RTLD_NOW); if (!lib_handle) { fprintf(stderr, "%s\n", dlerror()); exit(EXIT_FAILURE); } typedef int (*func_ptr)(int); func_ptr func = (func_ptr)dlsym(lib_handle, "getInt"); std::cout << func(13); dlclose(lib_handle); }

我正在使用它编译它: g ++ -std = c ++ 11 -ldl loadlibtest.cpp -o main

我抓到的错误是./libshared.so:文件太短在我的if (!lib_handle) { 。

Right off the bat, I want to say that I've never worked with dynamic libraries so It's possible that I don't even understand how they work properly.

I want to have a fully loaded code running and after some trigger (probably user interaction) I want to load a specific library and execute a function inside that library. Preferably close it afterwards. Essentially allowing me to change it and re-load it during run time.

This is the simple dynamic library (called dynlib.so located in the same directory as the main code):

int getInt(int arg_0) { return (arg_0 + 7); }

And this is the main program:

#include <iostream> #include <dlfcn.h> int main() { void *lib_handle = dlopen("./dynlib.so", RTLD_LAZY | RTLD_NOW); if (!lib_handle) { fprintf(stderr, "%s\n", dlerror()); exit(EXIT_FAILURE); } typedef int (*func_ptr)(int); func_ptr func = (func_ptr)dlsym(lib_handle, "getInt"); std::cout << func(13); dlclose(lib_handle); }

I'm compiling it using: g++ -std=c++11 -ldl loadlibtest.cpp -o main.

The error I'm catching is ./libshared.so: file too short In my if (!lib_handle) {.

最满意答案

这对我来说可以。 我编译了dynlib.so

$ gcc dynlib.c -fPIC -shared -o dynlib.so

(显然,您需要将其编译为带有extern "C" C或C ++以避免名称损坏)。

我需要在g++调用中将-ldl放在源文件之后。

gcc:4.8.5; g ++:5.3.0


dlsym也可能失败,从void *到函数指针的转换在技术上是UB。 您应该将其基于联机帮助页中的用法代码段 (针对您的函数进行了修改):

dlerror(); /* Clear any existing error */ /* Writing: func = (int (*)(int)) dlsym(handle, "getInt"); would seem more natural, but the C99 standard leaves casting from "void *" to a function pointer undefined. The assignment used below is the POSIX.1-2003 (Technical Corrigendum 1) workaround; see the Rationale for the POSIX specification of dlsym(). */ *(void **) (&func) = dlsym(handle, "getInt"); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); exit(EXIT_FAILURE); }

It works fine for me. I've compiled dynlib.so with

$ gcc dynlib.c -fPIC -shared -o dynlib.so

(Obviously, you need to either compile it as C or C++ with extern "C" to avoid name mangling).

and I needed to place -ldl after the source file in the g++ invocation.

gcc: 4.8.5; g++: 5.3.0


dlsym may fail too and casting from void* to function pointers is technically UB. You should base it on the usage snippet from the manpage(modified for your function):

dlerror(); /* Clear any existing error */ /* Writing: func = (int (*)(int)) dlsym(handle, "getInt"); would seem more natural, but the C99 standard leaves casting from "void *" to a function pointer undefined. The assignment used below is the POSIX.1-2003 (Technical Corrigendum 1) workaround; see the Rationale for the POSIX specification of dlsym(). */ *(void **) (&func) = dlsym(handle, "getInt"); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); exit(EXIT_FAILURE); }