2

foo.h

#ifndef foo_h__
#define foo_h__ 
extern void foo(void); 
#endif

foo.c

#include <stdio.h>
#include "foo.h" 
void foo(void)
{
    puts("Hello, I'm a shared library");
}

を使用してコンパイル

gcc -Wall -fPIC -c foo.c
gcc -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o

dyna.c

#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h> 
typedef void (*foo)(void);
int main(int argc, char* argv[])
{
    void* lib;
    foo df;
    printf("argc: %d\n",argc);
    if(argc < 2)
        return printf("USAGE: %s lib-file\n", argv[0]);

    lib = dlopen(argv[1], RTLD_NOW);
    if(lib == NULL)
        return printf("ERROR: Cannot load library\n");

    df = dlsym(lib, "foo");
    if(df)
    {
    df();
    }
    else
        printf("ERROR: Invalid library\n");
    dlclose(lib);
}

を使用してコンパイル:

gcc -rdynamic -o dyna dyna.c -ldl

走る:

./dyna libfoo.so
argc: 2
ERROR: Cannot load library

どこがおかしいのかわからない...

4

2 に答える 2

4

dlopen(3)のマニュアルページを注意深く読んでください。

 If filename contains a slash ("/"), then it is interpreted as a
 (relative or absolute) pathname.  Otherwise, the dynamic linker 
 searches for the library as follows:

だからあなたは走るべきです

 ./dyna ./libfoo.so

また

 ./dyna $PWD/libfoo.so

LD_LIBRARY_PATHまたは、含むように設定することもできます.(これは推奨されません)

dlerror()PSは、エラー報告に使用することを忘れないでください。dlopenおそらく再入可能ではないことを覚えておいてください(したがって、マルチスレッドアプリケーションを使用している場合は、ミューテックスへの呼び出しdlopendlsymミューテックスを使用した呼び出しをシリアル化します)。

于 2013-02-25T07:46:46.257 に答える
2

実際には非常に単純で、ローダーは現在のディレクトリを検索しません。試す:

./dyna ./libfoo.so
       ^^^

他のすべてはよさそうだ。

于 2013-02-25T07:46:31.437 に答える