0

我有 2 个不同的库,其中包含与模板类相同的标头:

标头.hpp

template<typename T>
class Tpl1
{
public:
    static int field;
};

template<typename T>
int Tpl1<T>::field(7);

module1.cpp(共享库 1):

Tpl1<float> tpl;
std::cout << "f1: " << &tpl.field << std::endl;

module2.cpp(可执行文件):

Tpl1<float> tpl;
std::cout << "f2: " << &tpl.field << std::endl;

因此,在我的 linux 中,控制台应用程序具有: gcc (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3

结果,我看到了相同的指针地址。一切安好!

现在想象一下使用 android ndk r8e 和 gcc 4.7 工具链构建的原生 android 应用程序。

除了两个模块/库之外,我们还有一个 java 包装器来加载这两个本地库。哇!在 android 我看到不同的地址!

因此,本机 android 应用程序的编译器不会删除相同的模板实例化。我看到的原因是,对于 PC 构建,所有库都链接到单个二进制文件中,而对于 android,库被动态加载到 java 应用程序中。

有没有办法让同一个模板只有一个版本?我看到的唯一版本是将所有库链接到单个库中并将其链接到 java 代码中。

4

1 回答 1

0

这与模板实例化无关,真的!在链接期间,未解析的符号得到解析,并且重复的符号,例如来自模板实例化或未内联的内联函数(例如,因为它们的地址被占用),被合并。当使用共享库链接 hsppens 时,不知道将加载哪些其他共享库并且共享库之间的符号不一定会混淆。

C++ 标准对共享库没有任何要求,您可能需要以系统特定的方式解决问题。通常,将共享符号分解到另一个共享库中似乎是可行的,该共享库从其他共享库中使用。

于 2013-07-27T18:42:19.423 回答