如何在 onecodebase 中支持具有不同命名空间的两个版本的 third-party 库
How to support two versions of third-party libraries with different namespaces in onecodebase
我有两个版本的 third-party C++ 库(lib.so 和 header 文件)
在一个版本中,所有 classes/enums/structs 都在命名空间“A”中
在另一个版本中,它们位于命名空间“B”中
header 和 lib.so 名称在两个版本中都相同
我怎样才能拥有相同的代码库,以便我可以支持两个版本。像这样
if (myVersion == "1.0") {
/* pick all the symbols from namespace "A"*/
} else {
/* pick all the symbols from namespace "B"*/
}
您在代码中建议的是在运行时确定它,这在 C++ 中是不可能的。
如果您的版本不变,您可以将其声明为宏并使用预处理器进行调节。
如评论中所述,不建议使用 using namespace
,命名空间别名会更好。
#if VERSION == 1000 //...
namespace My = A;
#else
namespace My = B;
#endif
//使用我的::...
但是,如果您坚持使用using namespace
,
#define VERSION //your version
...
#if VERSION == 1000 //or something like that to mark 1.0.0.0
using namespace A;
#else
using namespace B;
#endif
使用下面的代码,我创建了两个包装器 .so(一个带有 version1 lib 和 -DVERSION=1,另一个带有 version2 lib 和 -DVERSION=2)
假设它们是 wlib1.so 和 wlib2.so
我将命名空间 A 或 B 中的 API(取决于我正在编译的内容)包装在 extern "C"
中
例如:
#define VERSION //your version
extern "C"
{
#if VERSION == 1 //or something like that to mark 1.0.0.0
using namespace A;
#else
using namespace B;
#endif
void foo_wrapper() {
foo();
// wlib1.so will have A::foo() and wlib2.so will have B::foo()
}
}
现在在用户端,我在 运行 时间使用了这样的东西:
using foo_t = void (*)();
foo_t foo_fp = nullptr;
void init(int ver)
{
std::string lib = "";
if (ver == 1) {
lib = "wlib1.so";
} else {
lib = "wlib2.so";
}
void* handle = dlopen(lib.c_str(), RTLD_LAZY);
foo_fp = reinterpret_cast<foo_t>(dlsym(handle, "foo_wrapper"));
}
/* use init(ver) before calling anything */
foo()
{
foo_fp();
}
因此用户可以在运行时间通过ver.
进行控制
我有两个版本的 third-party C++ 库(lib.so 和 header 文件) 在一个版本中,所有 classes/enums/structs 都在命名空间“A”中 在另一个版本中,它们位于命名空间“B”中 header 和 lib.so 名称在两个版本中都相同
我怎样才能拥有相同的代码库,以便我可以支持两个版本。像这样
if (myVersion == "1.0") {
/* pick all the symbols from namespace "A"*/
} else {
/* pick all the symbols from namespace "B"*/
}
您在代码中建议的是在运行时确定它,这在 C++ 中是不可能的。
如果您的版本不变,您可以将其声明为宏并使用预处理器进行调节。
如评论中所述,不建议使用 using namespace
,命名空间别名会更好。
#if VERSION == 1000 //...
namespace My = A;
#else
namespace My = B;
#endif
//使用我的::...
但是,如果您坚持使用using namespace
,
#define VERSION //your version
...
#if VERSION == 1000 //or something like that to mark 1.0.0.0
using namespace A;
#else
using namespace B;
#endif
使用下面的代码,我创建了两个包装器 .so(一个带有 version1 lib 和 -DVERSION=1,另一个带有 version2 lib 和 -DVERSION=2) 假设它们是 wlib1.so 和 wlib2.so
我将命名空间 A 或 B 中的 API(取决于我正在编译的内容)包装在 extern "C"
中例如:
#define VERSION //your version
extern "C"
{
#if VERSION == 1 //or something like that to mark 1.0.0.0
using namespace A;
#else
using namespace B;
#endif
void foo_wrapper() {
foo();
// wlib1.so will have A::foo() and wlib2.so will have B::foo()
}
}
现在在用户端,我在 运行 时间使用了这样的东西:
using foo_t = void (*)();
foo_t foo_fp = nullptr;
void init(int ver)
{
std::string lib = "";
if (ver == 1) {
lib = "wlib1.so";
} else {
lib = "wlib2.so";
}
void* handle = dlopen(lib.c_str(), RTLD_LAZY);
foo_fp = reinterpret_cast<foo_t>(dlsym(handle, "foo_wrapper"));
}
/* use init(ver) before calling anything */
foo()
{
foo_fp();
}
因此用户可以在运行时间通过ver.
进行控制