【问题标题】:how a function in shared library to link an un-implemented function?共享库中的函数如何链接未实现的函数?
【发布时间】:2009-11-04 14:55:10
【问题描述】:

是否可以创建一个共享库,其中存在一些未实现的功能?

我想创建一个共享库 testDele.so 并将 testDele.so 中的一些功能留给其他人使用,例如:

  1. 图书馆提供者制作文件:

====== testDele.c ==============

#include <stdlib.h>
#include "testDele.h"
const DELE * DELE_Init( void * udata)
{
   DELE * hnd = (DELE *) malloc(sizeof(DELE));
   hnd->udata = udata;   
   hnd->fun = &priFun;
   return hnd;
}

========== testDele.h ==============

extern int priFun(int a);
typedef int (*DELE_FUN)(int a);
typedef struct _dele
{
   void * udata;
   DELE_FUN fun;
} DELE ; 
const DELE * DELE_Init( void * udata);
  1. USER-B 实现文件

====== testDeleImp.c ==============

#inlucde "testDele.h"
#include <stdio.h>
int priFun(int a)    
{
        printf("testDele priFun:a=%d\n",a);
        return 1;    
}

====== testDeleMain.c ==============

#include "testDele.h"
int main()
{
   DELE * dele = DELE_Init(NULL);
   dele->fun(20);
   free (dele);
   return 1;    
}

那么当我(共享库提供者)编译共享库时

% gcc -shared -o libtestDele.so -fPIC testDele.c

出现以下错误

================================================ =

Undefined symbols:
  "_priFun", referenced from:
      _priFun$non_lazy_ptr in cceJPWAA.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

我知道这个错误是由未实现的函数 priFunc 引起的。但是 gcc 是否有任何参数可以防止链接未定义的符号?

【问题讨论】:

    标签: shared ld


    【解决方案1】:

    这绝对是可能的,我以前做过。

    我认为它可能已经在 C++ 中。我有一个带有未实现函数的类(这是合法的),它们被调用并将它们链接为静态库,我认为链接作为 SO 也有效..(我也不必做任何像虚拟函数这样的事情)

    我认为您的问题也可能是您直接从 C 文件转到 SO。

    尝试先编译成 object(.o) 文件,然后将其链接到 SO

    当我在一个可以访问它的地方时,我会尝试发布一些实际代码。

    【讨论】:

      【解决方案2】:

      问题是你在 DELE_Init 中将 priFun 的地址分配给 hnd->fun。所以链接器必须解析符号。如果您的代码直接调用该函数,则可以将其保留为未定义。

      extern int priFunc(int);
      int deleteFunc(int a)
      {
          return priFunc(a);
      }
      

      现在你可以把它编译成一个共享库了:

      %gcc -shared -o libdelete.so delete.c
      

      注意未定义的符号:

      %nm -u libdelete.so
      U priFunc
      

      但是,如果您的主应用程序调用 deleteFunc,则无法提前编译,因为 priFunc 未解析。您必须在源代码中提供它以供您的用户编译,因为他们缺少功能。

      如果您想以可执行格式提供库和应用程序。那么我的建议是:

      存根解决方案

      创建一个包含所有用户函数的存根共享库。创建库时链接到此存根。然后您的用户在运行时提供他们的库作为替代品。

      动态库解决方案

      坚持使用函数指针。但是使用 dlopen() 之类的东西来加载用户库和函数。

      userlib = argv[1];
      dld = dlopen(userlib, RTLD_LAZY);
      priFunc = dlsym(dld, "priFun");
      delete = DELE_Init(udata, priFunc);
      delete->fun(20);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-27
        • 2010-12-23
        • 2023-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-09
        相关资源
        最近更新 更多