使用 dlopen() 对象时确定调用对象
我正在编写一个(C)程序,它通过 dlopen() 使用插件系统。我遇到的绊脚石是主程序导出一些函数,这些函数确实需要知道调用它们的插件(主要是记录保存,因此插件可以正确卸载,因为它们添加了诸如函数指针之类的东西到主程序)程序)。
我似乎无法找到一种干净的方法来做到这一点。到目前为止我提出的选项:
- 要求插件提供其名称,或者我在加载时提供的一些数据作为函数的参数。
- 我不喜欢这个选项,因为并不是所有的函数都关心它们是从谁那里调用的,所以它使它变得不一致和混乱。另外,我想让插件尽可能难以撒谎
- 使用 backtrace() 来确定前一个函数的对象名称。
- 这看起来相当丑陋且不可移植。
- 要求插件放置一个包含其名称的文件级结构(或其他变量)(我们将其称为“plugin_info”以供讨论)。然后在加载插件时使用 dlsym() 来查找变量并按其名称对其进行索引(就像在哈希中一样)。然后放入插件用来调用函数的 #define 宏,并让宏添加
&plugin_info
作为参数。- 这就是我现在正在使用的,但它看起来很黑客。对于一个,你必须让宏传递“&plugin_info”,如果你只传递“plugin_info”,那么它会从主程序而不是插件中提取“plugin_info”。通过地址引用它似乎可以使其使用正确的地址进行编译,并且不会被重新定位。这让我不喜欢这个选项,因为这看起来像是它的未定义行为,但它确实有效。此外,当插件开发人员在函数调用方面遇到问题(传递错误的参数类型或诸如此类的问题)时,宏也会使其变得有点混乱。
如果有任何其他想法或技术,我很想知道。
I'm writing a (C) program which utilizes a plugin system via dlopen(). The stumbling block I'm running across is that the main program exports a few functions which really need to know the plugin that called them (mostly record keeping, and so a plugin can be unloaded properly as they add things like function pointers to the main program).
I cant seem to find a clean way to do this. The options I've come up with so far:
- require the plugin to provide its name, or some data I give it on load as an argument to the functions.
- I dont like this option because not all functions care who they were called from, so it makes it inconsistent and messy. Plus I would like to make it as difficult as possible for the plugin to lie about who it is
- Use backtrace() to determine the object name of the previous function.
- This just seems fairly ugly and non-portable.
- Require the plugin to put a file-level struct (or other variable) containing its name (lets call it 'plugin_info' for discussion). Then use dlsym() when loading the plugin to look up the variable and index it (like in a hash) by its name. Then put in #define macros which the plugins use to call the functions and have the macro add
&plugin_info
as an argument.- This is what I'm using now but it seems hackish. For one you have to have the macro pass '&plugin_info', if you just pass 'plugin_info' then it pulls the 'plugin_info' from the main program, not the plugin. Referencing it by address seems to make it so that its compiled with the correct one, and that it doesnt get relocated. That makes me dislike this option as that seems like its undefined behavior, however it does work. Also the macros can make it a bit confusing when the plugin developer has a problem with the function call (passing wrong argument type or whatnot).
If there's any other ideas or techniques, I would love to love to know.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
rm -rf ~
。如果这是一个问题,您需要将其沙箱到一个没有特权的单独进程中。static
添加到plugin_info
的定义中,您将拥有完美定义的行为,并且不会出现任何黑客行为。rm -rf ~
if it likes. If this is a problem, you need to sandbox it in a separate process without privileges.static
toplugin_info
's definition and you'll have perfectly well-defined behavior and none of the hackery.