我有一个问题,自几个星期以来一直无法解决。
我确定有解决方案,也许这里有个主意。

有一个名为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实现的细节。这很容易导致麻烦,尤其是将来更改库时。

09-30 18:07
查看更多