如何让这个用于加载模块的简单 C 测试程序正常工作?

发布于 2024-10-31 06:18:34 字数 566 浏览 7 评论 0 原文

我打算在 linux 上使用 dlopen 和 dlsym 来使这两个源文件工作:

 #include <dlfcn.h>
 #include <stdio.h>
 int main()
 {
     int *(func)(void);

     func=dlsym( dlopen("/home/noah/tmp/libmod.so.1", RTLD_LAZY), "func");

     printf("%d\n", *func());
     return 0;
}

and:

int func()
{
return 42;
}

但是当我编译第一个文件时,它一直说:

main.c:9: 错误:需要左值作为赋值的左操作数

编辑的左操作数: 我尝试添加强制转换,并将其设为函数指针,但现在它说: main.c:(.text+0x1f): 对 dlopen' 的未定义引用 main.c:(.text+0x2b): 对 dlsym' 的未定义引用

I was going to use dlopen, and dlsym on linux to make these two source files work:

 #include <dlfcn.h>
 #include <stdio.h>
 int main()
 {
     int *(func)(void);

     func=dlsym( dlopen("/home/noah/tmp/libmod.so.1", RTLD_LAZY), "func");

     printf("%d\n", *func());
     return 0;
}

and:

int func()
{
return 42;
}

but when I compile the first one, it keeps saying:

main.c:9: error: lvalue required as left operand of assignment

edit:
I tried adding a cast, and making it a function pointer, but now it says:
main.c:(.text+0x1f): undefined reference to dlopen'
main.c:(.text+0x2b): undefined reference to
dlsym'

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

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

发布评论

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

评论(3

剩一世无双 2024-11-07 06:18:34

您的 func 声明很混乱:

int *(func)(void);

相当于:

int *func(void);

所以您只是为编译器提供了 func 的原型,而不声明变量;发生错误的原因是函数不是有效的左值;但是,指向函数的指针是有效的左值,因此您需要这样:

int (*func)(void);

然后您的printf应该是这样:

printf("%d\n", func());

您还需要转换的返回值>dlsym 严格符合标准 C:

func = (int (*)(void))dlsym(dlopen("/home/noah/tmp/libmod.so.1", RTLD_LAZY), "func");

void* 指针可以静默升级为除函数指针之外的任何其他指针类型;例如,gcc -pedantic 会警告“ISO C 禁止在函数指针和‘void *’之间进行赋值”,而无需强制转换。我手头没有标准的副本(但这里肯定有人有),所以我不能引用章节和诗句,但咖啡馆在这一点上是正确的(感谢咖啡馆)。

您还想为 cdecl.org 添加书签。

Your declaration of func is confused:

int *(func)(void);

is equivalent to:

int *func(void);

so you're just giving the compiler a prototype for func without declaring a variable; the error occurs because a function is not a valid lvalue; however, a pointer to a function is a valid lvalue so you want this:

int (*func)(void);

And then your printf should be this:

printf("%d\n", func());

You'll also need to cast the return from dlsym to be strictly conforming to standard C:

func = (int (*)(void))dlsym(dlopen("/home/noah/tmp/libmod.so.1", RTLD_LAZY), "func");

A void* pointer can be silently upgraded to any other pointer type except a pointer to a function; gcc -pedantic, for example, will warn that "ISO C forbids assignment between function pointer and ‘void *’" without the cast. I don't have a copy of the standard handy (but someone around here certainly does) so I can't quote chapter and verse but caf is correct on this point (thanks caf).

And you also want to bookmark cdecl.org.

嘿看小鸭子会跑 2024-11-07 06:18:34

你不能真正做你正在尝试的事情,

但它应该是 int (func*)()

并且 printf 应该是 func()

但你不能将 dlsym 及其所有参数分配为函数指针

提示......函数指针“func”只是一个指针,它没有状态,它只是一个内存地址

,你不应该提供一个名为 func 的函数......因为你正在创建一个名为 func 的指针。你可以创建一个函数“int test_function(){ return 42; }

然后在 main go func = test_function; 只是使用函数指针进行测试

you can't really do what you are attempting

but it should be int (func*)()

and the printf should be func()

but you can't assign the dlsym with all its parameters as a function pointer

hint.... the function pointer "func" is just a pointer, it has no state, its just a memory address

and you shouldn't provide a function called func..... as you are making a pointer called func. you could make a function "int test_function(){ return 42; }

then in main go func = test_function; just to test using the function pointer

流殇 2024-11-07 06:18:34

不需要 *func()

printf("%d\n", func());

就可以了,因为 func() 将返回 int,并且您尝试获取整数的解引用 (*)

查看运算符的优先级(链接

There is no need to *func()

printf("%d\n", func());

will be ok, cause func() will return the int, and you try to get dereference (*) of integer

look at precedence of operators (link)

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