0

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

我想创建一个共享库 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 是否有任何参数可以防止链接未定义的符号?

4

2 回答 2

0

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

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

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

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

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

于 2009-11-04T15:12:25.870 回答
0

问题是您将 priFun 的地址分配给 DELE_Init 中的 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);
于 2009-12-04T15:35:28.443 回答