gpt4 book ai didi

firefox-addon - 带有重复项的复杂动态和静态链接(Firefox 附加组件、WebRTC 和 VP8)

转载 作者:行者123 更新时间:2023-12-04 05:52:36 25 4
gpt4 key购买 nike

我试图以抽象的方式表述问题,但无论如何我最后都会提供有关实际库的详细信息。

动态库 Addon 与其他库 WebRTC 静态链接,后者在汇编中有一些代码,此代码作为目标文件链接到 WebRTC连同 WebRTC 自己的对象文件。让我们调用此汇编代码 VP8VP8的功能在WebRTC中被标记为externAddon 中的某些函数 Encode() 调用 WebRTC 的函数,最终调用 VP8 的函数。

现在,要加载库 Addon 的应用程序 Firefox 非常复杂,并且有自己的库版本(意味着静态链接)WebRTC(我们称它为 WebRTC2),但它是一个较旧的代码。

所以,这里有一个问题:如果从应用程序 Firefox 调用 Encode(),则调用 WebRTC 函数(不是 WebRTC2,这是正确的)但是WebRTC 尝试调用 VP8 函数时,它们从 WebRTC2 版本(表示应用程序的 WebRTC 版本),但不是来自 WebRTC

有没有办法强制 WebRTC 只从 VP8 的本地副本进行调用?

Application Firefox 是一个 Firefox 浏览器,WebRTC 是一个 WebRTC 库,VP8 是一个 VP8 编解码器库(在 WebRTC 中)和 Addon 是我的 Firefox C++ 插件。

更新 - 详细说明

这里是问题的“非抽象”描述:所以有一个 C++ XPCOM 附加组件静态链接到最新版本的 WebRTC 库。在加载项内部的某个时刻,调用了对帧进行编码(VP8Encoder 类的方法 Encode),它一直在 Firefox 中崩溃,但继续运行良好在使用 gtest 框架的测试程序上。

问题在于,在 WebRTC 内部的某个时刻,有 VP8 汇编代码被调用以进行编码,并且该汇编代码的函数在实现文件中声明为 extern。实际上,它在 vp8_intra_pred_y_ve_sse2 函数上崩溃。我比较了这个函数的三个汇编代码:一个来 self 的 WebRTC 版本(在附加组件中使用),第二个 - 调试器崩溃的地方,第三个 - 来自 Mozilla 的 WebRTC 的源代码。

事实证明,由于某些奇怪的原因,Mozilla 的代码被调用而不是附加组件的 WebRTC(当然它们具有相同的名称)并且由于 Mozilla 的 WebRTC 代码已过时,它因 EXC_BAD_ACCESS 而崩溃。

最佳答案

这可能对你没有太大帮助,但由于没有其他人回应,我开始......

您没有提到您是在 Linux、Windows 还是其他平台上运行。我的答案是针对 Linux。我相信 Windows 加载动态库的方式不同。

我认为正在发生的事情是您已经静态链接到 WebRTC 库 stub 接口(interface),并且这些 stub 接口(interface)动态链接到实际实现,然后将 WebRTC 库的第一个实例加载到 firefox 而不是第二个实例。确保您真正链接到 WebRTC 库的静态编译版本。

linux dlopen(3) 手册页列出了一个有趣的标志,它似乎对如果您的库是加载 WebRTC 库的库有帮助:

   void *dlopen(const char *filename, int flag);

dlopen()

  The function dlopen() loads the dynamic library file named by the null-
terminated string filename and returns an opaque "handle" for the
dynamic library. [...]

RTLD_DEEPBIND (since glibc 2.3.4)

Place the lookup scope of the symbols in this library ahead of
the global scope. This means that a self-contained library will
use its own symbols in preference to global symbols with the
same name contained in libraries that have already been loaded.
This flag is not specified in POSIX.1-2001.

不幸的是,firefox 是加载您的库的那个。

如果您的库动态链接到 WebRTC(看起来是这样)并且您使用带有 RTLD_DEEPBIND 标志的 dl_open() 显式加载了您想要的 WebRTC 库,那么这将解决您的问题。

这对您没有多大帮助,因为绑定(bind)到 vp8_intra_pred_y_ve_sse2 的不是您的代码,但值得指出的是 gcc 也有 dlsym() 函数,它可以拿几个特殊的标志:

   void *dlsym(void *handle, const char *symbol);

dlsym()

   The  function dlsym() takes a "handle" of a dynamic library returned by
dlopen() and the null-terminated symbol name, returning the address
where that symbol is loaded into memory. [...]

There are two special pseudo-handles, RTLD_DEFAULT and RTLD_NEXT. The
former will find the first occurrence of the desired symbol using the
default library search order. The latter will find the next occurrence
of a function in the search order after the current library. This
allows one to provide a wrapper around a function in another shared
library.

您可以在您的代码中使用它来至少调试正在发生的事情,方法是让它打印出它为查找 vp8_intra_pred_y_ve_sse2 而获得的值。

最后,同一个手册页指出 linux 有一个 dlvsm() 也接受一个版本字符串参数,允许 XPCOM 代码指定它想要的函数版本:

   #define _GNU_SOURCE         /* See feature_test_macros(7) */
#include <dlfcn.h>

void *dlvsym(void *handle, char *symbol, char *version);

如果是我,并且我被迫动态链接这些东西,我会采用蛮力方法。进入库并更改函数名称(在两个库中)。不优雅,每当这两个库的新版本出来都会让人头疼,但它简单直接。

关于firefox-addon - 带有重复项的复杂动态和静态链接(Firefox 附加组件、WebRTC 和 VP8),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18731128/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com