覆盖函数指针后面的c静态函数

覆盖函数指针后面的c静态函数,c,static,shared-libraries,overriding,C,Static,Shared Libraries,Overriding,我有一个问题,几个星期以来一直无法解决。 我相信有一个解决方案,也许这里有一个想法 有一个名为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) { st

我有一个问题,几个星期以来一直无法解决。 我相信有一个解决方案,也许这里有一个想法

有一个名为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\u INFO\u 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 the libaudio.so的进程相同,因此我也可以调用dlopen(“libaudio.so”),并将获得与以前进程相同的对此库的引用

我也可以调用dlsym(HAL_MODULE_INFO_SYM),然后获得相同的公共结构。 然后我可以调用open和*open\u output\u stream*,然后理论上更改指向write函数的指针

但是,从我开始的C语言知识来看,这不会影响流程的实例,只会影响我自己的实例

这意味着:进程在其实例后面仍然有原始的write-函数,只有我的实例才会调用my_write_函数

我不知道如何强制进程重新加载HAL\u模块信息\u SYM并调用HAL\u模块信息\u SYM->方法->打开(设备)-因此更改此符号无效

我不能更改外部代码,也不能更改libaudio.so。我只能访问我自己的小libplugin.so


如果有人能帮助我,我将非常感激。

我认为这是可以做到的,但前提是你在调用libaudio.so之前进行干预

那时,您可以在
libaudio.so
中获得
HAL\u MODULE\u INFO\u SYM
的地址(按照您的建议,使用
dlopen
),将
方法
指针复制到某个地方,并将其替换为指向您自己方法结构的指针。该结构中的方法只需从保存的指针调用原始方法。
就其本身而言,这没有任何作用,但是您的
open
方法可以在调用真实的
open
后,查看返回的
dev
并对其进行操作

如果您没有及时完成,进程已经有了它的
dev
指针,我认为您无法更改它


但我想提醒大家,这一切似乎都很脆弱,取决于
libaudio.so
实现的细节。这很容易导致麻烦,特别是如果将来更改库。

您希望覆盖函数指针而不是实际的函数代码,对吗?还有,我猜你要找的符号不是从库中导出的?libaudio.so是如何构造和构建的?正如我所说的,我对C语言比较陌生,所以我不明白你问的所有问题。但我知道,调用我的libplugin.so的进程以前称为handle=dlopen('libaudio.so',现在称为RTLD_);dlsym(手柄、HAL\u模块\u信息\u SYM)->方法->打开(设备);和设备->打开输出流(..)。除了libplugin.so以外的所有代码都不在我的范围内,并且在一个不受我控制的运行系统上。
out->stream.write
等。您知道变量
out
未初始化,指向la-la-land吗?它不指向已分配的内存。当然这不可能是真正的代码,请发布它。如果这是真实的代码,那么函数指针是众多严重问题中最小的一个……哦,你说得对。编辑,谢谢!是的,这会起作用,但遗憾的是,我的插件是在libaudio之后加载的。因此,顺序无法更改:)我几乎没有寻找强制重新加载该部分的方法。。