丢失的符号应该存在

时间:2010-01-18 09:11:28

标签: c linux symbols shared-objects

我很难过。这是ld。

的输出
/usr/lib/libvisual-0.6/actor/actor_avs_superscope.so: undefined reference to `visual_mem_free'
/usr/lib/libvisual-0.6/actor/actor_avs_superscope.so: undefined reference to `visual_mem_malloc0'

以下是宏:

#define visual_mem_new0(struct_type, n_structs)           \
    ((struct_type *) visual_mem_malloc0 (((visual_size_t) sizeof (struct_type)) * ((visual_size_t) (n_structs))))

#define visual_mem_malloc(size)     \
    visual_mem_malloc_impl (size, __FILE__, __LINE__, __PRETTY_FUNCTION__)

#define visual_mem_malloc0(size)    \
    visual_mem_malloc0_impl (size, __FILE__, __LINE__, __PRETTY_FUNCTION__)

#define visual_mem_realloc(ptr, size)   \
    visual_mem_realloc_impl (ptr, size, __FILE__, __LINE__, __PRETTY_FUNCTION__)

#define visual_mem_free(ptr)        \
    visual_mem_free_impl (ptr, __FILE__, __LINE__, __PRETTY_FUNCTION__)

现在它没有加起来。有一行说缺少visual_mem_free,这是一个宏。另一个说是缺少visual_mem_malloc0,但是代码实际上调用了visual_mem_new0,这表明它看到了visual_mem_new0。

priv = visual_mem_new0 (SuperScopePrivate, 1);

visual_mem_free (priv);

任何线索?

编辑:颠簸..也许一些新鲜的眼睛可以帮助?

编辑:顺便说一句,我在编译期间没有警告/错误,也没有链接。

编辑:这是预处理器输出中的几个片段。

int lv_superscope_cleanup (VisPluginData *plugin)
{
 SuperScopePrivate *priv = visual_object_get_private ((((VisObject*) ((plugin)))));

 visual_mem_free_impl (priv, "actor_avs_superscope.c", 195, __PRETTY_FUNCTION__);

 return 0;
}

 priv = ((SuperScopePrivate *) visual_mem_malloc0_impl (((visual_size_t) sizeof (SuperScopePrivate)) * ((visual_size_t) (1)), "actor_avs_superscope.c", 152, __PRETTY_FUNCTION__));

看起来宏正在扩展。我糊涂了。是__PRETTY_FUNCTION__应该扩展吗?

有趣的是,这是字符串的输出。

$ strings .libs/actor_avs_superscope.so |grep malloc
visual_mem_malloc0_impl
visual_mem_malloc0
malloc

克里斯:我刚刚开始ld /usr/lib/libvisual-0.6/actor/actor_avs_superscope.so

这是nm的输出:

$ nm actor_avs_superscope.o |grep malloc
         U visual_mem_malloc0_impl

$ nm actor_avs_superscope.o |grep free
         U visual_mem_free_impl
         U visual_palette_free_colors

4 个答案:

答案 0 :(得分:3)

C代码中的宏不会在编译的可执行文件中生成符号。可能正在发生的事情是你正在编译的一些代码没有#include这些宏,所以编译器推断它们是函数,并编译了对它们的调用。您可以使用-Wall-Werror来调用未定义的函数,但无法编译。

答案 1 :(得分:1)

感觉它不是在阅读你的#define - 尝试在它们之间打印一条消息只是为了检查。

同时检查文件编译的顺序;对visual_mem_new0的调用是在#define之后吗?

答案 2 :(得分:1)

在链接之前的预处理阶段处理宏。因此,如果链接编辑器给你关于宏名称的警告,那么宏就不会被扩展。

要查看预处理的结果,可以使用/ E标志。如果您的宏已经展开,您会看到以下行:

visual_mem_free (priv);

改为:

visual_mem_free_impl(priv, "filename.c", 32, "main");

<强>更新

从您的nm /字符串输出中,文件actor_avs_superscope.o不是问题所在。还有哪些其他对象(.o)文件和静态存档(.a)用于创建actor_avs_superscope.so?您应该在所有这些上运行nm,以便找到其中包含未展开的宏名称的人。

答案 3 :(得分:0)

您的第一个错误是针对已安装的库/usr/lib/libvisual-0.6/actor/actor_avs_superscope.so,看起来您正在查看项目strings .libs/actor_avs_superscope.so中的本地库。尝试针对/usr/lib中的字符串运行字符串,您可能会看到问题。

我可以在运行时安装更新的库版本或将其目录放在LD_LIBRARY_PATH中,类似$ LD_LIBRARY_PATH=./lib ./your_executable