我有一个问题,自几个星期以来一直无法解决。
我确定有解决方案,也许这里有个主意。
有一个名为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的libaudio.so相同的进程下运行,因此我也可以调用dlopen(“libaudio.so”),并将获得与以前的进程相同的对该库的引用。
我还可以调用dlsym(HAL_MODULE_INFO_SYM),然后将获得相同的 public 结构。
然后,我可以调用open和* open_output_stream *,然后从理论上从调用,将指向的指针更改为-函数。
但是,从我开始的C知识开始,这不会影响流程的实例,只会影响我自己的实例。
这意味着:该进程在其实例后面仍保留原始的写入-函数,只有我的实例会调用 MY_WRITE_FUNCTION 。
我知道没有办法强制该过程重新加载 HAL_MODULE_INFO_SYM 并重新调用 HAL_MODULE_INFO_SYM->方法->打开(设备)-因此更改此符号将无效。
我无法更改外部代码,也无法更改libaudio.so。我只能访问自己的小libplugin.so。
如果有人可以帮助我,我将非常感谢。
最佳答案
我认为可以做到,但是只有在之前干预的情况下,该过程才会调用libaudio.so
。
到那时,您可以在HAL_MODULE_INFO_SYM
中获得libaudio.so
的地址(按照您的建议使用dlopen
),将methods
指针复制到某处,并用指向您自己的方法结构的指针替换。该结构中的方法将仅从保存的指针中调用原始方法。
它本身无法实现任何目的,但是您的open
方法可以在调用真正的open
之后查看返回的dev
并对其进行操作。
如果您没有及时进行操作,则该进程已经具有其dev
指针,而我看不到可以对其进行更改的方法。
但我想警告您,这一切似乎都很脆弱,并且取决于libaudio.so
实现的细节。这很容易导致麻烦,尤其是将来更改库时。