共享库中的函数如何链接未实现的函数?

问题描述 投票:0回答:2

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

我想创建一个共享库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
2个回答
0
投票

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

我认为它可能是在C ++中。我有一个未实现的函数(这是合法的)被调用并将它们作为静态库链接起来的类,我认为链接作为SO也可以工作..(我也不需要像虚函数那样做)

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

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

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


0
投票

问题是你在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);
© www.soinside.com 2019 - 2024. All rights reserved.