马上,我想说我从未使用过动态库,所以我甚至不知道它们是如何正常工作的。
我希望运行一个完全加载的代码,并在一些触发器(可能是用户交互)之后,我想加载一个特定的库并在该库中执行一个函数。 最好在之后关闭它。 基本上允许我在运行时更改它并重新加载它。
这是一个简单的动态库(名为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); }
发布评论