如何在ruby中使用FFI::Library卸载或指定二进制.so库?

eiee3dmh  于 12个月前  发布在  Ruby
关注(0)|答案(1)|浏览(118)

我有一个ethon gem,它可以按行加载libcurl库:

ffi_lib_flags :now, :global
ffi_lib ['ibcurl.so', 'libcurl.so.4']
extend Ethon::Curls::Functions # it attaches functions from libcurl

我做了一个猴子补丁

ffi_lib_flags :now, :global
ffi_lib '/home/myuser/libs/libcurl.so'
attach_function :easy_impersonate, :curl_easy_impersonate, [:pointer, :string, :int], :int # attach custom function from patched libcurl
extend Ethon::Curls::Functions # it attaches default functions from patched libcurl

FFI找到了curl_easy_impersonate函数,但是当我调用它时,我得到了一个代码48(在libcurl文档中,这意味着没有找到这样的函数)。
但是,如果我直接将gem ffi_lib '/home/myuser/libs/libcurl.so'中的这一行替换为ffi_lib '/home/myuser/libs/libcurl.so',则调用此函数将返回0,并且它将按照我所希望的方式工作。我认为这是因为FFI首先访问gem加载的库。

问题:有没有什么方法可以用FFI卸载这个库,或者显式地指定哪个库用于函数调用?
**P.S.**我想用monkey-patch来做,我不想分叉gem只改变一行,在生产中支持它会很不方便。

试图删除附加的方法,找到要删除的带有方法ffi_libraries的libcurl库对象,试图找到加载的libcurl的任何踪迹,但找不到。

ia2d9nvy

ia2d9nvy1#

我不认为FFI库提供了卸载已加载库的方法。
如果你需要“卸载”一个库,你将需要在FFI::Library本身之外处理它。您可以尝试重新启动Ruby进程。
或者,您可以在加载FFI绑定之前尝试此操作,您可以设置LD_LIBRARY_PATH环境变量以指定修补后的www.example.com所在的目录libcurl.so。这种方式改变了加载器使用的库搜索路径,并允许Ruby脚本从LD_LIBRARY_PATH中指定的目录中获取打过补丁的libcurl.so

相关问题