我有一个问题,几周以来我都无法解决。我确信有一个解决方案,也许这里有一个想法。
有一个名为libaudio.so的共享库,如下所示:
static ssize_t out_write(..)
{
// /!\ I need to overwrite/extend this function
return 0;
}
static int adev_open_output_stream(struct audio_stream_out **stream_out)
{
struct stream_out *out;
out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
if (!out)
return -ENOMEM;
out->stream.write = out_write; // pointer to static function above
*stream_out = &out->stream;
return 0;
}
static int adev_open(hw_device_t** device)
{
struct audio_device *adev;
adev = calloc(1, sizeof(struct audio_device));
if (!adev)
return -ENOMEM;
adev->hw_device.open_output_stream = adev_open_output_stream; // pointer to static function above
*device = &adev->hw_device.common;
return 0;
}
static struct hw_module_methods_t hal_module_methods = {
.open = adev_open, // this function can be called after obtained via dlsym() below
};
struct audio_module HAL_MODULE_INFO_SYM = {
.methods = &hal_module_methods, // this field is public available and can be called via dlsym()
};
我的代码(也是一个名为libplugin.so的共享库)在进程下作为插件运行。
这个进程之前打开了 libaudio.so(上图),获得了 *HAL_MODULE_INFO_SYM* 并调用了
HAL_MODULE_INFO_SYM->methods->open(device)
我无法访问进程的设备实例,所以我不能只用
struct audio_stream_out **stream_out
device->open_output_stream(stream_out)
stream_out.write = MY_WRITE_FUNCTION
但在这里我的希望是:
由于我在之前 dlopen'd libaudio.so的同一进程下运行,我也可以调用 dlopen("libaudio.so") 并且将获得与之前的进程相同的对该库的引用。
我也可以调用 dlsym(HAL_MODULE_INFO_SYM) 然后将获得相同的公共结构。然后我可以调用open和 *open_output_stream* ,然后理论上将指针更改为write函数。
但是,以我开始的 C 知识,这不会影响进程的实例,只会影响我自己的实例。
这意味着:该进程在他的实例后面仍然具有原始的write函数,并且只有我的实例会调用MY_WRITE_FUNCTION。
我知道没有办法强制进程重新加载HAL_MODULE_INFO_SYM并调用HAL_MODULE_INFO_SYM->methods->open(device) - 因此更改此符号不起作用。
我无法更改外部代码,也无法更改 libaudio.so。我只能访问我自己的小 libplugin.so。
如果有人可以帮助我,我会非常感激。