C++ 外部符号的可视性和可移植性

C++ 外部符号的可视性和可移植性,c++,linker,extern,C++,Linker,Extern,我正在尝试创建一个特殊的.cpp文件,它将有一个const char*version,其中包含包版本,编译后它将链接到库和包中的可执行文件。库和可执行文件将其引用为extern符号,如下所示: version.cpp const char* version=VERSION_STRING; 版本.h extern const char* version; 库和可执行文件中的代码 #include "version.h" 现在的问题是,可执行文件必须询问库版本库,但由于符号是extern,其实

我正在尝试创建一个特殊的.cpp文件,它将有一个
const char*version
,其中包含包版本,编译后它将链接到库和包中的可执行文件。库和可执行文件将其引用为
extern
符号,如下所示:

version.cpp

const char* version=VERSION_STRING;
版本.h

extern const char* version;
库和可执行文件中的代码

#include "version.h"
现在的问题是,可执行文件必须询问库版本库,但由于符号是
extern
,其实例的名称发生冲突,结果是,即使库版本不同,可执行文件也认为它是相同的

我曾尝试使用
-fvisibility=hidden
gcc选项或相应的
\uuuu属性(事实上,它的包装是glib:
G\u GNUC\u INTERNAL
)来避免这种情况,但困扰我的是它根本不可移植,也就是说,我不确定它在Windows中如何工作

因此,问题是:在更改版本时,有什么更干净的方法可以避免过多的重新编译,并且在不牺牲可移植性的情况下仍然没有外部可见(给定二进制之外)的版本符号

  • 可执行文件必须向库“询问”版本(在这种情况下,符号不应该是外部的,库应该只提供一些
    const char*lib\u get\u version()
    函数)
  • 或者符号应该是外部的,并且对可执行文件直接可见,在这种情况下,它应该只由库提供。也就是说,version.cpp将链接到库中,但不会链接到可执行文件,因此库为最终可执行文件提供符号
第一个选项可能是最简单和最便携的


对于可能不相同的两个版本:

  • 创建两个单独的文件,例如
    lib_version.cpp
    bin_version.cpp
    ,分别导出
    const char*get_lib_version()
    const char*get_bin_version()
  • 将第一个cpp文件编译到lib中,将第二个cpp文件编译到bin中
  • 如果被版本化的东西是相同的,比如说如果bin和lib有不同版本的某些API,那么创建一个由两个cpp文件使用的私有头

    // header_impl.h
    #define VERSION_STRING "1.2.3"
    
    // lib_version.h
    const char *get_lib_version();
    
    // lib_version.cpp (linked only in lib)
    #include <version_impl.h>
    const char *get_lib_version() { return VERSION_STRING; }
    
    // bin_version.h
    const char *get_bin_version();
    
    // bin_version.cpp (linked only in bin)
    #include <version_impl.h>
    const char *get_bin_version() { return VERSION_STRING; }
    
    //头\u impl.h
    #定义版本\字符串“1.2.3”
    //lib_version.h
    const char*get_lib_version();
    //lib_version.cpp(仅在lib中链接)
    #包括
    const char*get_lib_version(){return version_STRING;}
    //bin_版本.h
    const char*get_bin_version();
    //bin_version.cpp(仅在bin中链接)
    #包括
    const char*get_bin_version(){return version_STRING;}
    
    现在,lib和bin都包含编译时版本的shapshot,来自version_impl头。您可以在没有链接器冲突的情况下获取这两个值


  • 要解决交叉编译代码中的版本控制问题,通常有以下方法:

    - both the library and app have their own .cpp file.
     - the library includes a getLibVersion() function in the API to get the library version.
     - the app has access to this getLibVersion() and either calls it to build a larger string containing both lib and app string(eg. 16bit for app, 16 bit for lib giving a 32 bit string) or provides a wrapper for this function which can be called from the app API.
    
    底线-有两个version.cpp文件(lib+app)-如果lib版本发生更改,您必须重新构建应用程序-应用程序在其API中提供功能,以分别获取版本或连接版本


    希望这有帮助

    可执行文件和库可能有不同的版本,必须正确报告这两个版本,这是问题的核心。啊,你的问题是“版本”,单数。