构建共享库,但未定义对函数的引用?

时间:2011-03-29 01:10:58

标签: compiler-construction linker shared-libraries visibility

我有一个我正在为练习而构建的基本共享库,它所定义的是

形式的函数占位符
int placeholder() { return 1; }

我正在使用libtool在makefile中构建它以便于(相关部分):

libfootest: $(OBJECTS)
    libtool --mode=link $(CC) -g -O -o libfootest.la $(OBJECTS)\
          -rpath /usr/lib

libfootest.o: $(SRCDIR)/$(SOURCES)
    libtool --mode=compile $(CC) -c $(SRCDIR)/$(SOURCES)

install: libfootest
    libtool --mode=install cp libfootest.la /usr/lib/libfootest.la

现在我可以验证a)它是否安装了相应的.so.*.la,b)nm在单个libtool对象中定义了符号placeholder(在链接之前的libfootest.o),我相信这就是我所需要的。

我现在正在创建一个用于测试目的的程序,

#include "../includes/libfootest.h" //public prototypes are here
int main() {
  int test = placeholder();
  return 0;
}

链接它就像-lfootest并且找到它,虽然不幸的是我得到了一个未定义的引用错误的引用错误!

/tmp/cc92NtSa.o: In function `main':
prototypes.cxx:(.text+0x19): undefined reference to `placeholder()'

你能否发现我在这方面做错了什么,或者是否有某种导出我必须为图书馆工作?我看到一些apis在他们的函数声明之前使用了DLLEXPORT或类似的东西,我不确定他们做了什么。

1 个答案:

答案 0 :(得分:1)

prototypes.cxxC++模式编译,导致placeholder()引用获取C++名称链接(并获取mangled)。

如果您希望placeholder()同时CC++都可以调用,则必须在extern "C"模式下构建时将C++链接添加到其原型中:

#ifdef __cplusplus
extern "C"
#endif
int placeholder();

如果您希望placeholder()只能从C++使用,请使用CXX代替CC构建库。