无法从C中的其他模块访问Linux中共享库的自定义全局函数

时间:2018-02-12 17:26:43

标签: c linux shared-libraries

我已下载libgcrypt库源代码和 在一个特定文件中添加了我自己的自定义功能

虽然自定义共享库的编译/构建过程成功,但 nm和objdump都显示  自定义函数是全局的它在链接时显示错误(未定义的引用)。

这就是我所做的:

在/src/visibility.c文件中,我添加了自定义函数

void __attribute__((visibility("default"))) MyFunction(void)
{
    printf("This is added just for testing purpose");   
}

构建过程

./configure --prefix=/usr/local --disable-ld-version-script

sudo make install

nmobjdump命令将此自定义函数作为全局内部共享库。

nm /usr/local/lib/libgcrypt.so | grep MyFunction
000000000000fbf0 T MyFunction


objdump -t /usr/local/lib/libgcrypt.so | grep MyFunction
000000000000fbf0 g     F .text  0000000000000013              MyFunction

以下是访问我的自定义函数的示例代码。

//gcrypt_example_test.c
#include <stdio.h>
#include <gcrypt.h>
#include <assert.h>

int main()
{
    MyFunction();
    return 0;
}


export LD_RUN_PATH=/usr/local/lib
gcc gcrypt_example_test.c -o test -lgcrypt
  

/tmp/ccA0qgAB.o:在函数`main'中:   gcrypt_example_test.c :(。text + 0x3a2):对“MyFunction”的未定义引用   collect2:错误:ld返回1退出状态

修改1:

我尝试了所有可能的方法在头文件(/src/gcrypt.h)中包含函数原型声明,如下所示:

   void __attribute__((visibility("default"))) MyFunction(void);   

......或:

    extern void __attribute__((visibility("default"))) MyFunction(void);  

......或:

    extern void   MyFunction(void);

......或:

    void   MyFunction(void);

我仍然遇到同样的错误(undefined reference),但在上述所有情况下都没有出现构建错误。

为什么会发生这种情况,我犯了什么错误?

虽然其他全局函数是标准共享库的一部分,并在visibility.cnm中也为这些函数显示T)中定义,但是为什么我的自定义全局函数({ {1}})共享库仍然无法访问?谢谢!

任何解决此错误的链接或解释都会非常明显。

4 个答案:

答案 0 :(得分:4)

来自the GCC documentation(强调我的):

  

某些链接器允许您通过在链接时在环境中设置LD_RUN_PATH来指定库的路径。

但是,from the GNU ld man page

   -rpath=dir
       Add a directory to the runtime library search path.  This is used
       when linking an ELF executable with shared objects.  All -rpath
       arguments are concatenated and passed to the runtime linker,
       which uses them to locate shared objects at runtime.  The -rpath
       option is also used when locating shared objects which are needed
       by shared objects explicitly included in the link; see the
       description of the -rpath-link option.  If -rpath is not used
       when linking an ELF executable, the contents of the environment
       variable "LD_RUN_PATH" will be used if it is defined.

请注意,链接时间库搜索路径没有提及。

您需要在链接时间库搜索路径中编译/链接/usr/local/lib

gcc gcrypt_example_test.c -o test -L/usr/local/lib -lgcrypt

答案 1 :(得分:1)

最有可能导致问题:

库的头文件尚未更新,以包含新功能的原型

答案 2 :(得分:1)

我不明白为什么它现在正在工作的原因,但不是之前。无论如何,我在标准库中添加自定义函数后找到了使代码工作的方法。这篇文章可能在将来帮助其他人。

我首先找到libgcrypt.so,然后删除所有版本的libgcrypt.so

locate libgcrypt.so


sudo rm /usr/local/lib/libgcrypt.so 
sudo rm /usr/local/lib/libgcrypt.so.20 
sudo rm /usr/local/lib/libgcrypt.so.20.2.2

然后我删除了libgcrypt文件夹(我为构建库提取了它)以重新开始。

再次,我按照这些步骤进行操作

第0步:提取libgcrypt源代码

步骤1:在/src/visibility.c文件中添加我的自定义函数

void __attribute__((visibility("default"))) MyFunction(void)
{
    printf("This is added just for testing purpose");   
}

第2步:构建库

export LD_RUN_PATH=/usr/local/lib
./configure --prefix=/usr/local --disable-ld-version-script
sudo make install

步骤3:打开另一个终端进行编译

export LD_RUN_PATH=/usr/local/lib
gcc gcrypt_example_test.c -o test -lgcrypt

第4步:运行

./test
This is added just for testing purpose

现在按预期工作正常。

我注意到函数定义中 __ attribute __((visibility(&#34;默认&#34;))) - disable-ld-version-script 在构建过程中非常重要的是使定制函数全局化,消除任何使得定制函数本地在共享库(.so)文件中。

答案 3 :(得分:0)

以下更改正在我的最后工作

<强> visibility.h

#include <cstdio>

void __attribute__((visibility("default"))) MyFunction(void);

<强> visibility.cpp

#include "visibility.h"


void MyFunction(void)
{
    printf("This is added just for testing purpose");
}

库构建命令

gcc -shared -o libtest.so -Wall -Werror -fpic -I. visibility.cpp

<强> TEST.CPP

#include <stdio.h>
#include <gcrypt.h>
#include <assert.h>
#include "visibility.h"

extern void MyFunction();

int main()
{
  MyFunction();
  return 0;
}

exe build命令

gcc test.cpp -o test -I. -L. -ltest -lstdc++

我的gcc版本是4.4.7

当然,我没有尝试在/ usr / local / lib下安装lib,但是将其保存在本地以便快速测试。