C 库的 C++ 包装器作为共享库

Posted

技术标签:

【中文标题】C 库的 C++ 包装器作为共享库【英文标题】:C++ Wrapper for C library as shared library 【发布时间】:2012-12-14 12:54:21 【问题描述】:

我自己解决了这个问题

问题是图书馆的链接。 我将 libmywrapper.so(我将其重命名)文件复制到 /usr/lib 并与 -mywrapper 链接 就是这样:-)

原帖:

我正在编写一个允许从 C 代码调用 C++ 函数的包装库。 不幸的是它没有链接......

包装器.h:

#ifdef __cplusplus
extern "C"

#endif
    extern char* (keygen) ();
#ifdef __cplusplus
 
#endif

包装器.cpp:

#include "wrapper.h"
#include <someincludes>
char* keygen ()

    urandom u;

生成文件:

TARGET      := ./mywrapperlib.so
CXXFLAGS    := -fPIC -shared -g -Wall -std=c++0x -I../someincludes -I.
CXX         := g++
LIB         := -lsomelibs
EXT         := cpp
BUILDDIR    := build

override BUILDDIR := $(strip $(BUILDDIR))
SOURCES  := $(wildcard *.$(EXT))
OBJECTS  := $(patsubst %.$(EXT), $(BUILDDIR)/%.o, $(SOURCES))
DEPS     := $(patsubst %.$(EXT), $(BUILDDIR)/%.dep, $(SOURCES))

.PHONY: all
all: $(TARGET)

$(TARGET): $(OBJECTS) $(DEPS)
    $(CXX) $(CXXFLAGS) -o $(TARGET) $(OBJECTS) $(LIBS)

ifneq ($(MAKECMDGOALS), clean)
-include $(DEPS)
endif

$(OBJECTS): $(BUILDDIR)/%.o: %.$(EXT) $(BUILDDIR)/%.dep $(BUILDDIR)/.tag
    $(CXX) $(CXXFLAGS) -c $< -o $@

$(DEPS): $(BUILDDIR)/%.dep: %.$(EXT) $(BUILDDIR)/.tag
    mkdir -p $(dir $(@))
    $(CXX) $(CXXFLAGS) -MM $< -MT $@ -MT $(<:.$(EXT)=.o) -o $@

%.tag:
    mkdir -p $(dir $(@))
    touch $@

.PHONY: clean
clean:
    $(RM) -r $(BUILDDIR)

应该使用该库的测试文件: 测试.c:

#include <wrapper.h>
int main()

    char* test = keygen();

当我尝试用它编译时

gcc  -o test.a -g -Iinclude -Llib/mywrapperlib.so test.c

我明白了

/tmp/ccB9bEot.o: In function `main':
/some/paths/test.c:7: undefined reference to `keygen'

我对混合 C 和 C++ 代码以及编写库非常缺乏经验。 现在我卡住了,希望有人能帮我解决这个问题。

编辑:

我用 nm 检查了库:

nm lib/cryptdbwrapperlib.so | grep keygen
0000000000006935 T keygen

所以,我想问题出在链接上……

【问题讨论】:

问题标题在你写的时候有意义吗? ;) 我修正了拼写错误和标题 ;-) 如果您解决了问题,请发布答案。请不要在问题中写出解决方案。 呃,标题是不是倒过来了?现在的标题说您正在从 C++ 调用 C 库。我想你真的想说你正在从 C 调用一个 C++ 共享库。 【参考方案1】:

这与你的标志到gcc的顺序有关。

这样做:

gcc  -o test.a -g -Iinclude test.c -Llib/mywrapperlib.so
#                           ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
#                           first    second

GCC 从左到右读取库和对象,并且(基本上)忽略“还”不需要的任何内容。在我提议的更改中,test.c 首先出现,因此 GCC 知道它将寻找符号 keygen;然后,当它最终看到-Llib/mywrapperlib.so 时,它会扫描keygen,找到它,并知道这个库是必需的。

【讨论】:

请注意真正的问题,该行没有链接到共享对象,它只是指定了一个(无效)路径来搜索库(-L ,也需要一个 -l 参数并且可能是共享的库应该命名为 libmywrapper.so 所以你可以做 -Llib -lmywrapper)【参考方案2】:

wrapper.cpp中的函数签名改为

extern "C" char* keygen ()

否则它将使用 C++ 样式名称进行编译,因此是与头文件中声明的函数不同的函数。

【讨论】:

不,只需要在初始声明中指定链接即可。【参考方案3】:

我自己解决了这个问题

问题在于图书馆的链接。我将 libmywrapper.so(我将其重命名)文件复制到 /usr/lib 并与 -mywrapper 链接就是这样:-)

【讨论】:

以上是关于C 库的 C++ 包装器作为共享库的主要内容,如果未能解决你的问题,请参考以下文章

CMake、SWIG 和共享库

在 C++ 共享库的标头中声明“外部“C””有啥影响?

有没有人有在 MATLAB 中创建共享库的经验?

使用Android Studio调试C ++库

Windows 和 Linux 上动态库的 C++ 标准 [关闭]

如何使用共享库构建 vtkLocal 示例?