对dlsym /的dlopen与运行参数 [英] dlsym/dlopen with runtime arguments

查看:252
本文介绍了对dlsym /的dlopen与运行参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做类似以下

  enum types {None, Bool, Short, Char, Integer, Double, Long, Ptr};
  int main(int argc, char ** args) {
     enum types params[10] = {0};
     void* triangle = dlopen("./foo.so", RTLD_LAZY);
     void * fun = dlsym(triangle, ars[1]);

     <<pseudo code>>
  }

当伪code是一样的东西。

Where pseudo code is something like

fun = {}
for param in params:
      if param == None:
         fun += void
      if param == Bool:
          fun += Boolean
      if param == Integer:
          fun += int
      ...
 returnVal = fun.pop()
 funSignature = returnval + " " + funName + "(" + Riffle(fun, ",") + ")"
 exec funSignature

感谢您

推荐答案

其实,你几乎可以做你想要的所有。在C语言(与C ++不同,例如)在共享对象的功能仅仅是通过它们的名字引用。因此,要找到 - 和,什么是最重要的,要的呼叫的 - 适当的功能,你不需要它的全部签名。你只需要它的名字!这既是优势和劣势 - 但是这就是你选择了语言的本质。

Actually, you can do nearly all you want. In C language (unlike C++, for example), the functions in shared objects are referenced merely by their names. So, to find--and, what is most important, to call--the proper function, you don't need its full signature. You only need its name! It's both an advantage and disadvantage --but that's the nature of a language you chose.

让我演示一下,它是如何工作。

Let me demonstrate, how it works.

#include <dlfcn.h>

typedef void* (*arbitrary)();
// do not mix this with   typedef void* (*arbitrary)(void); !!!

int main()
{
    arbitrary my_function;
    // Introduce already loaded functions to runtime linker's space
    void* handle = dlopen(0,RTLD_NOW|RTLD_GLOBAL);
    // Load the function to our pointer, which doesn't know how many arguments there sould be
    *(void**)(&my_function) = dlsym(handle,"something");
    // Call something via my_function
    (void)  my_function("I accept a string and an integer!\n",(int)(2*2));
    return 0;
}

在事实上,你可以调用任何函数的方式。然而,有一个缺点。实际上,你的需要知道你的函数在编译时的返回类型。默认情况下,如果你在一个省略的typedef无效*,INT假定为返回类型 - 而且,是的,这是一个正确的C code。问题是,编译器需要知道返回类型的大小正常运行堆栈。

In fact, you can call any function that way. However, there's one drawback. You actually need to know the return type of your function in compile time. By default, if you omit void* in that typedef, int is assumed as return type--and, yes, it's a correct C code. The thing is that the compiler needs to know the size of the return type to operate the stack properly.

您可以通过招数变通办法,例如,pre-声明几个函数类型与预先大小不同的返回类型,然后选择你实际上要调用哪一个。但是,简单的解决方案是要求功能你的插件返回void *或总是诠释;通过作为参数指针返回的实际结果。

You can workaround it by tricks, for example, by pre-declaring several function types with different sizes of return types in advance and then selecting which one you actually are going to call. But the easier solution is to require functions in your plugin to return void* or int always; the actual result being returned via pointers given as arguments.

那你必须确保的是,你随时拨打准确数量和类型的它应该接受参数的函数。密切注意不同的整数类型之间的差异(您最好的选择将是显式转换参数它们)。

What you must ensure is that you always call the function with the exact number and types of arguments it's supposed to accept. Pay closer attention to difference between different integer types (your best option would be to explicitly cast arguments to them).

一些评论报道,的code以上不能保证可变参数的函数工作(如的printf )。

Several commenters reported that the code above is not guaranteed to work for variadic functions (such as printf).

这篇关于对dlsym /的dlopen与运行参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆