tags:

views:

15

answers:

2

Is it possible to make a shared library in which exist some function that are not implemented?

I'l like to make a shared library testDele.so and leave some of the functions in the testDele.so to be implimented by other people for example:

  1. library provider make the files:

====== 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 implements the files

====== 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;    
}

then when I (shared library provider) compile the shared library

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

the following error occured

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

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

I know this error is caused by the un-implemented function priFunc. But is there any parameters of gcc to prevent from linking the undefined symbols?

thanks a lot.

A: 

This is definately possible, I have done this before.

I think it may have been in C++ though. I had a class with unimplemented functions(which is legal) that were called and linking them as a static library worked, and I think linking as a SO worked also.. (I didn't have to do anything like virtual functions either)

I think your problem might also be that you are going straight from a C file to an SO.

Try compiling to an object(.o) file first and then linking that into an SO

I'll try to post some actual code in a little bit when I'm at a place with access to it.

Earlz
A: 

The problem is that you are assigning the address of priFun to hnd->fun in DELE_Init. So the linker must resolve the symbol. If your code calls the function directly, then it can be left undefined.

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

Now you can compile this into a shared library:

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

Note the undefined symbol:

%nm -u libdelete.so
U priFunc

However, your main application cannot be compiled ahead of time if it calls deleteFunc because priFunc is unresolved. You must provide it in source code for your user to compile as they have the missing function.

If you want to provide both the library and your application in executable format. Then my suggestions are:

stub solution

Create a stub shared library containing all the user functions. Link against this stub when you create your library. Then your user provide their library as a replacement at run-time.

dynamic library solution

Stick with function pointers. But use something like dlopen() to load user libraries and functions.

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