我的主要问题是为什么数组会做如此奇怪的事情,以及是否有任何方法可以以“干净”的方式执行以下操作。
我目前有一个 C 程序通过foo.c连接 Fortran 程序,大致如下代码所示:bar.f90dlopen/dlsym
foo.c:
#include <dlfcn.h>
#include <stdio.h>
int main()
{
int i, k = 4;
double arr[k];
char * e;
void * bar = dlopen("Code/Test/bar.so", RTLD_NOW | RTLD_LOCAL);
void (*allocArray)(int*);
*(void **)(&allocArray) = dlsym(bar, "__bar_MOD_allocarray");
void (*fillArray)(double*);
*(void **)(&fillArray) = dlsym(bar, "__bar_MOD_fillarray");
void (*printArray)(void);
*(void **)(&printArray) = dlsym(bar, "__bar_MOD_printarray");
double *a = (double*)dlsym(bar, "__bar_MOD_a");
for(i = 0; i < k; i++)
arr[i] = i * 3.14;
(*allocArray)(&k);
(*fillArray)(arr);
(*printArray)();
for(i = 0; …Run Code Online (Sandbox Code Playgroud) 我有一个共享库,我想从主程序访问符号。例如:
main.c
#include <stdio.h>
void bar(void) { puts("bar"); }
extern void foo(void);
int main(void) {
foo();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
foo.c
#include <stdio.h>
extern void bar(void);
void foo(void) {
puts("foo");
bar();
}
Run Code Online (Sandbox Code Playgroud)
我编译并运行如下:
gcc -c -fpic foo.c
gcc -shared -o libfoo.so foo.o
gcc -L$(pwd) -o test main.c -lfoo
./test
Run Code Online (Sandbox Code Playgroud)
我得到了我期望的输出:
foo
bar
Run Code Online (Sandbox Code Playgroud)
但是,我必须使用dlopen()anddlsym()因为我想控制库的加载时间。更改的文件是:
main.c
#include <stdio.h>
#include <dlfcn.h>
void bar(void) { puts("bar"); }
int main(void) {
void *handle = dlopen("./libfoo.so", RTLD_LAZY);
void (*foo)(void) = (void(*)(void))dlsym(handle,"foo");
foo();
return …Run Code Online (Sandbox Code Playgroud) 我有一个位于共享对象中的函数,并dlsym从主程序加载和执行。(共享对象和主程序都是C++)
这个函数有可能返回吗std::unique_ptr?
共享对象函数 -
extern "C" {
unique_ptr<Obj> some_function() {
return make_unique<Obj>();
}
}
Run Code Online (Sandbox Code Playgroud)
主程序:
void main_flow() {
auto handle = dlopen(...);
FuncPtr func = dlsym(handle, "some_function");
unique_ptr<Obj> func();
}
Run Code Online (Sandbox Code Playgroud) dlsym可以从剥离的二进制文件中导入函数,这很奇怪.
谁能告诉我为什么/如何?
=== FILE: a.c ===
int a1() { return 1; }
int a2() { return 2; }
=== end of a.c ===
=== FILE: b.c ===
#include <stdio.h>
#include <dlfcn.h>
#include <stdlib.h>
typedef int (*fint)();
fint dlsym_fint(void *handle, char *name)
{
fint x = (fint)dlsym(handle, name);
char *err = NULL;
if ((err = dlerror()) != NULL) {
printf("dlsym: %s\n", err);
exit(1);
}
return x;
}
int main()
{
void *dl = dlopen("a.so", RTLD_NOW);
fint a = NULL;
a = …Run Code Online (Sandbox Code Playgroud) 我有两个相同行为的实现,我认为应该产生相同的结果,但相反产生不同的结果.在Go using中编译时cgo,我获得了与在C中编译时不同的符号地址解析.我想了解原因.
我将问题简化为几个小例子,一个在C中,一个在Go中.我在Mac笔记本电脑上运行的Ubuntu 18 Docker容器中测试了这些.
test.c的:
// gcc test.c -D_GNU_SOURCE -ldl
// Output: Real: 0x7fd05559d7d0 Current: 0x7fd05559d7d0
#include <dlfcn.h>
#include <stdio.h>
int main() {
void * fd = dlopen("libc.so.6", RTLD_LAZY);
void * real_sym = dlsym(fd, "accept");
void * curr_sym = dlsym(RTLD_NEXT, "accept");
printf("Real: %p Current: %p\n", real_sym, curr_sym);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
test.go:
// go build test.go
// Output: Real: 0x7f264583b7d0 Current: 0x7f2645b1b690
package main
// #cgo CFLAGS: -D_GNU_SOURCE
// #cgo LDFLAGS: -ldl
// #include <dlfcn.h>
import "C"
import …Run Code Online (Sandbox Code Playgroud) host.cpp有:
int main (void)
{
void * th = dlopen("./p1.so", RTLD_LAZY);
void * fu = dlsym(th, "fu");
((void(*)(int, const char*)) fu)(2, "rofl");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
并且p1.cpp具有:
#include <iostream>
extern "C" bool fu (float * lol)
{
std::cout << "fuuuuuuuu!!!\n";
return true;
}
Run Code Online (Sandbox Code Playgroud)
(我故意留下错误检查出来)
当执行主机时,"fuuuuuuuu !!!"被正确打印,即使我将带有完全不同功能签名的符号的void指针类型化.
为什么会发生这种情况,这种行为在不同的编译器之间是否一致
我曾经用来dlopen加载一个对象并dlsym获得一个指向共享对象函数的函数指针.一切正常.我测试了它然后调用共享功能(现在)只打印它工作 - 在主程序调用它打印好.现在我想向这个函数传递两个参数.An int和a char *.任何人都可以帮助我理解如何将参数传递给共享函数?我在网上搜索过但我无法理解它是如何工作的.
我试图通过使用dlopen和dlsym获取函数指针,但是我无法使其正常工作。尝试执行dlsym调用时失败。以下是我的代码。
有什么帮助吗?
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
int test() {
printf("%s", "test()");
return 123;
}
int main() {
char * functionname = "test";
void* handle = dlopen(NULL,RTLD_LAZY|RTLD_GLOBAL);
if (!handle) {
fprintf(stderr, "Couldn't open handle: %s\n",
dlerror());
exit(1);
}
int (*fun)() = (int (*)())dlsym(handle, functionname);
if (fun == NULL) {
fprintf(stderr, "Couldn't find function: %s\n",functionname);
exit(1);
}
int a = fun();
printf("result: %d \n", a);
}
Run Code Online (Sandbox Code Playgroud) 我想动态链接共享库并从中分配一个函数std::function.这是代码:
function.cpp:
#include <array>
#ifdef __cplusplus
extern "C" {
#endif
double function(std::array<double, 1> arg)
{
return arg[0] * 2;
}
#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)
main.cpp中:
#include <functional>
#include <iostream>
#include <fstream>
#include <array>
#include <functional>
#ifdef __linux__
#include <dlfcn.h>
#endif
int main()
{
void *handle;
double (*function)(std::array<double, 1>);
char *error;
handle = dlopen("/home/oleg/MyProjects/shared_library_test/libFunction.so", RTLD_LAZY);
if (!handle)
{
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
dlerror();
*(void **) (&function) = dlsym(handle, "function");
if ((error = dlerror()) != NULL)
{
fprintf(stderr, "%s\n", …Run Code Online (Sandbox Code Playgroud) dlsym ×9
c ×4
c++ ×3
dlopen ×3
linux ×2
arguments ×1
casting ×1
cgo ×1
extern-c ×1
fortran ×1
fortran2003 ×1
go ×1
std-function ×1
strip ×1
unique-ptr ×1