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 ++にあったかもしれないと思います。呼び出された未実装の関数 (合法) を持つクラスがあり、それらをスタティック ライブラリとしてリンクすることができました。

あなたの問題は、CファイルからSOに直行していることにもあると思います。

最初にオブジェクト (.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

ただし、 priFuncが解決されていないため、deleteFuncを呼び出す場合、メイン アプリケーションを事前にコンパイルすることはできません。不足している関数があるため、ユーザーがコンパイルできるようにソース コードで提供する必要があります。

ライブラリとアプリケーションの両方を実行可能形式で提供する場合。次に、私の提案は次のとおりです。

スタブ ソリューション

すべてのユーザー関数を含むスタブ共有ライブラリを作成します。ライブラリを作成するときに、このスタブにリンクします。次に、ユーザーは実行時にライブラリを代替として提供します。

動的ライブラリ ソリューション

関数ポインターに固執します。ただし、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 に答える