【发布时间】:2015-02-23 08:45:52
【问题描述】:
我有 c++ 库 .so。我的同事正在开发 c 程序,该程序将从他的 c 程序中调用 c++ 库。我告诉他创建 Wrapper.h 和 Wrapper.cpp 并使用指针在他的 c 程序中传递 c++ 对象。但是,我发现他试图通过将 Wrapper.cpp 和 header 直接添加到我们的库 .so 中来修改我们的 c++ 库源代码。例如:
class A{ SetValueA(int); }
class B{ SetValueB(int); }
在他的 Wrapper.cpp 中,他是这样写的:
A a;
B b;
extern "C" SetValueA(int) {a.SetValueA(int); }
extern "C" SetValueB(int) {b.SetValueB(int); }
然后他重新编译了我们的 c++ 库,并将 Wrapper.h 包含在他的 c 程序中。
我告诉他的是这样做: 在我的 Wrapper.cpp 中
extern "C" {
A* newClassA() {
return new A();
}
void SetValueA(A* v, int i) {
v->SetA(i);
}
B* newClassB() {
return new B();
}
void SetValueB(B* v, int i) {
v->SetB(i);
}
void deleteClassA(A* v) {
delete v;
}
void deleteClassB(B* v) {
delete v;
} }
然后我刚刚编译了我的 Wrapper.cpp 并与我们的 c++ 库链接。在他的 c 程序中,他只需要包含 Wrapper.h 并编译他的 c 代码,然后使用 c++ 编译器编译 Wrapper.o 和 main.o(来自 main.c)。
他的解决方案看起来也很有效,他抱怨说我告诉他的方式更有效。但我不希望他更改我们的 c++ 库,因为没有其他人会使用 c++ 库中的 Wrapper 类。你能告诉我哪个更好,为什么?
是的,我也不喜欢他在包装器中使用全局变量的方式。
【问题讨论】:
-
我更喜欢他的解决方案,因为他只需要将 c++ 库与他的 c 程序链接起来,并且只调用 c 接口函数。使用您的解决方案,他必须链接到 c++ 库,并使用 c++ 编译器编译包装器,然后链接到两者。这一切都取决于您是否更喜欢编辑库以包含 c 接口,这是一个偏好。所以这完全取决于你们。
-
@Brandon:他需要链接到 C++ 库并创建一个 C++ 编译的包装文件。
-
是的,但对于其中一个,他只是编辑库以包含一个 c 接口并重新编译它。然后他所要做的就是链接到它。第二种方式需要他制作包装器并链接到库以编译包装器。然后在他的 c 程序中,链接到包装器和库。至少我是这么理解的?还是我解释错了?
-
@Brandon:我认为实际上存在多个相互交织的问题:包装代码所在的组织就是其中之一。我对此没有太多意见,但我可以想象 C++ 库的 C 包装器成为库的一部分。另一个问题是包装器应该是什么样子,我对此有相当强烈的看法:全局变量总是不如其他方法。
-
@Brandon,我的解决方案需要使用与库链接的 g++ 编译 Wrapper.o,使用 gcc 编译 main.o,然后将 Wrappe.o 和 main.o 与与库链接的 g++ 结合起来,但我的库提供通用 c++ API。没有其他人会使用他图书馆里的 Wrapper。