[习题29]C语言:库与链接 dlopen( )

2018-12-28  本文已影响21人  AkuRinbu

使用教材

《“笨办法” 学C语言(Learn C The Hard Way)》
https://www.jianshu.com/p/b0631208a794

https://github.com/zedshaw/learn-c-the-hard-way-lectures/tree/master/ex29

命令行操作

$ cc -fPIC -c libex29.c -o libex29.o
$ ls
dbg.h  ex29.c  libex29.c  libex29.o

$ cc -shared -o libex29.so libex29.o
$ ls
dbg.h  ex29.c  libex29.c  libex29.o  libex29.so

$ cc -Wall -g -DNDEBUG ex29.c -ldl -o ex29
$ ls
dbg.h  ex29  ex29.c  libex29.c  libex29.o  libex29.so

$ ./ex29 ./libex29.so print_a_message "hello world"
A STRING: hello world

$ ./ex29 ./libex29.so uppercase "hello there"
HELLO THERE

$ ./ex29 ./libex29.so lowercase "HELLO WorlD"
hello world
$ ./ex29 ./libex29.so fail_on_purpose "i fall"
[ERROR] (ex29.c:27: errno: None) Function fail_on_purpose return 1 for data: i fall
$ ./ex29 ./libex29.so fail_on_purpose
[ERROR] (ex29.c:10: errno: None) USAGE: ex29 libex29.so function data

$ ./ex29 ./libex29.so are_you_here?
[ERROR] (ex29.c:10: errno: None) USAGE: ex29 libex29.so function data
$ ./ex29 ./libex29.so are_you_here? are_you?
[ERROR] (ex29.c:23: errno: None) Did not find are_you_here? function in the library ./libex29.so: ./libex29.so: undefined symbol: are_you_here?

$ ./ex29 ./lib.so aaaaaa ccccccc
[ERROR] (ex29.c:18: errno: None) Failed to open the library ./lib.so: ./lib.so: cannot open shared object file: No such file or directory

完整源码

libex29.c

#include <stdio.h>
#include <ctype.h>
#include "dbg.h"


int print_a_message(const char *msg)
{
    printf("A STRING: %s\n", msg);

    return 0;
}


int uppercase(const char *msg)
{
    int i = 0;

    // BUG: \0 termination problems
    for(i = 0; msg[i] != '\0'; i++) {
        printf("%c", toupper(msg[i]));
    }

    printf("\n");

    return 0;
}

int lowercase(const char *msg)
{
    int i = 0;

    // BUG: \0 termination problems
    for(i = 0; msg[i] != '\0'; i++) {
        printf("%c", tolower(msg[i]));
    }

    printf("\n");

    return 0;
}

int fail_on_purpose(const char *msg)
{
    return 1;
} 

ex29.c

#include <stdio.h>
#include "dbg.h"
#include <dlfcn.h>

typedef int (*lib_function) (const char *data);

int main(int argc, char *argv[])
{
    int rc = 0;
    check(argc == 4, "USAGE: ex29 libex29.so function data");

    char *lib_file = argv[1];
    char *func_to_run = argv[2];
    char *data = argv[3];

    void *lib = dlopen(lib_file, RTLD_NOW);
    check(lib != NULL, "Failed to open the library %s: %s", lib_file,
            dlerror());

    lib_function func = dlsym(lib, func_to_run);
    check(func != NULL,
            "Did not find %s function in the library %s: %s", func_to_run,
            lib_file, dlerror());

    rc = func(data);
    check(rc == 0, "Function %s return %d for data: %s", func_to_run,
            rc, data);

    rc = dlclose(lib);
    check(rc == 0, "Failed to close %s", lib_file);

    return 0;

error:
    return 1;
}

概念解释

代码说明

[举 例 说 明]
/****    ex29.c    ****/
  char *lib_file = argv[1];
  char *func_to_run = argv[2];
  char *data = argv[3];
/****    ex29.c    ****/

$  ./ex29     ./libex29.so   print_a_message   "hello world"
argv[1] = ./libex29.so  
argv[2] = print_a_message  
argv[3] = hello world 

参考资料

  • 解决:/usr/bin/ld: libex29.o: relocation R_X86_64_32 against `.rodata'
    can not be used when making a shared object; recompile with -fPIC
    libex29.o: error adding symbols: Bad value
    collect2: error: ld returned 1 exit status
    https://www.jianshu.com/p/91edc58041fb
上一篇下一篇

猜你喜欢

热点阅读