dl备忘

参考文档

Dynamic Library Programming
linphone AudioTrack

cpp class demo
/* File: Person.cpp */
#include <iostream>
#include "Person.h"
 
#define EXPORT __attribute__((visibility("default")))
 
EXPORT Person::Person() {
    char default_name[] = "<no value>";
    this->set_name(default_name);
}
 
EXPORT Person::Person(char *name) {
    this->set_name(name);
}
 
EXPORT Person::~Person() {
    printf("~Person %s\n", _person_name);
}

EXPORT Person* NewPerson(void) {
    return new Person;
}
 
EXPORT Person* NewPersonWithName(char name[]) {
    return new Person(name);
}
 
EXPORT void DeletePerson(Person* person) {
    delete person;
}
 
EXPORT void Person::set_name(char name[]) {
    strcpy(_person_name, name);
}
 
EXPORT char* Person::myname(void) {
    return _person_name;
}
/* File: Person.h */
#include <cstring>
class Person {
    private:
        char _person_name[30];
    public:
        Person();
	~Person();
        Person(char* name);
        virtual void set_name(char person_name[]);
        virtual char* myname();
};
 
// Constructor functions and function types.
extern "C" Person* NewPerson(void);
typedef Person * Person_creator(void);
extern "C" Person* NewPersonWithName(char name[]);
typedef Person * PersonWithName_creator(char name[]);
 
// Destructor function and function type.
extern "C" void DeletePerson(Person* person);
typedef void Person_disposer(Person*);
/* File: Client.cpp */
#include <iostream>
#include <dlfcn.h>
#include "Person.h"

class MyPerson {};
typedef void *(*Person_new)(MyPerson *);
typedef char *(*Person_myname)(MyPerson *);
typedef void (*Person_setName)(MyPerson *, char[]);
typedef void (*Person_release)(MyPerson *);

int main() {
    using std::cout;
    using std::cerr;
    
    // Open the library.
    void *lib_handle = dlopen("./libPerson.so", RTLD_NOW);
    if (!lib_handle) {
        cout << "[" << __FILE__ << "] load libPerson.so failed " << "\n";
        exit(EXIT_FAILURE);
    }

    // Person::Person()
    Person_new _person_new = (Person_new) dlsym(lib_handle, "_ZN6PersonC1Ev");
    if (!_person_new) {
        exit(EXIT_FAILURE);
    }
    // char* Person::myname(void)
    Person_myname _person_myname = (Person_myname) dlsym(lib_handle, "_ZN6Person6mynameEv");
    if (!_person_myname) {
        exit(EXIT_FAILURE);
    }
    // void Person::set_name(char name[])
    Person_setName _person_setName = (Person_setName) dlsym(lib_handle, "_ZN6Person8set_nameEPc");
    if (!_person_setName) {
        exit(EXIT_FAILURE);
    }
    // Person::~Person()
    Person_release _person_release = (Person_release) dlsym(lib_handle, "_ZN6PersonD1Ev");
    if (!_person_release) {
        exit(EXIT_FAILURE);
    }

    MyPerson *instance = (MyPerson *) malloc(sizeof(MyPerson));
    _person_new(instance);
    
    char *_my_name = _person_myname(instance);
    cout << "[" << __FILE__ << "] old name " << _my_name << "\n";
    
    char _new_name[] = "<hello world>";
    _person_setName(instance, _new_name);

    _my_name = _person_myname(instance);
    cout << "[" << __FILE__ << "] new name " << _my_name << "\n";

    _person_release(instance);
    delete instance;
    cout << "[" << __FILE__ << "] end " << "\n";
    // -----------------------------------------------------------------------------

    // Get the NewPerson function.
    Person_creator *NewPerson = (Person_creator *) dlsym(lib_handle, "NewPerson");
    if (!NewPerson) {
        exit(EXIT_FAILURE);
    }

    // Get the NewPersonWithName function.
    PersonWithName_creator *NewPersonWithName = (PersonWithName_creator *) dlsym(lib_handle, "NewPersonWithName");
    if (!NewPersonWithName) {
        exit(EXIT_FAILURE);
    }

    // Get the DeletePerson function.
    Person_disposer *DeletePerson =
            (Person_disposer *) dlsym(lib_handle, "DeletePerson");
    if (!DeletePerson) {
        exit(EXIT_FAILURE);
    }

    // Create Person objects.
    Person *person1 = NewPerson();
    char person_name[] = "Cendrine";
    Person *person2 = NewPersonWithName(person_name);
    cout << "[" << __FILE__ << "] person1->name() = " << person1->myname() << "\n";
    cout << "[" << __FILE__ << "] person2->name() = " << person2->myname() << "\n";

    // Use Person objects.
    char person1_name[] = "Floriane";
    person1->set_name(person1_name);
    cout << "[" << __FILE__ << "] person1->name() = " << person1->myname() << "\n";

    char person2_name[] = "Marcelle";
    person2->set_name(person2_name);
    cout << "[" << __FILE__ << "] person2->name() = " << person2->myname() << "\n";

    // Destroy Person objects.
    DeletePerson(person1);
    DeletePerson(person2);

    // Close the library.
    if (dlclose(lib_handle) != 0) {
        exit(EXIT_FAILURE);
    }
    return 0;
}

# 编译动态库
g++ -shared -fvisibility=hidden -fPIC -o libPerson.so Person.cpp

# 编译 client
g++ -o client  Client.cpp ./libPerson.so  -ldl
// 查看符号表
// nm libPerson.so 
0000000000004088 b completed.8060
                 U __cxa_atexit@@GLIBC_2.2.5
                 w __cxa_finalize@@GLIBC_2.2.5
0000000000001350 T DeletePerson
0000000000001100 t deregister_tm_clones
0000000000001170 t __do_global_dtors_aux
0000000000003db8 d __do_global_dtors_aux_fini_array_entry
0000000000004078 d __dso_handle
0000000000004080 d DW.ref.__gxx_personality_v0
0000000000003df0 d _DYNAMIC
0000000000001434 t _fini
00000000000011b0 t frame_dummy
0000000000003da8 d __frame_dummy_init_array_entry
0000000000002254 r __FRAME_END__
0000000000004000 d _GLOBAL_OFFSET_TABLE_
0000000000001419 t _GLOBAL__sub_I_Person.cpp
                 w __gmon_start__
0000000000002018 r __GNU_EH_FRAME_HDR
                 U __gxx_personality_v0@@CXXABI_1.3
0000000000001000 t _init
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
00000000000012ab T NewPerson
00000000000012f4 T NewPersonWithName
                 U printf@@GLIBC_2.2.5
0000000000001130 t register_tm_clones
                 U __stack_chk_fail@@GLIBC_2.4
                 U strcpy@@GLIBC_2.2.5
0000000000004088 d __TMC_END__
                 U _Unwind_Resume@@GCC_3.0
00000000000013cc t _Z41__static_initialization_and_destruction_0ii
                 U _ZdlPvm@@CXXABI_1.3.9
00000000000013b6 T _ZN6Person6mynameEv
0000000000001388 T _ZN6Person8set_nameEPc
000000000000122e T _ZN6PersonC1EPc
00000000000011ba T _ZN6PersonC1Ev
000000000000122e T _ZN6PersonC2EPc
00000000000011ba T _ZN6PersonC2Ev
000000000000126a T _ZN6PersonD1Ev
000000000000126a T _ZN6PersonD2Ev
                 U _ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.4
                 U _ZNSt8ios_base4InitD1Ev@@GLIBCXX_3.4
                 U _Znwm@@GLIBCXX_3.4
0000000000002000 r _ZStL19piecewise_construct
0000000000004089 b _ZStL8__ioinit
0000000000003de0 V _ZTI6Person
0000000000002010 V _ZTS6Person
0000000000003dc0 V _ZTV6Person
                 U _ZTVN10__cxxabiv117__class_type_infoE@@CXXABI_1.3

// 执行结果
./client 
[Client.cpp] old name <no value>
[Client.cpp] new name <hello world>
~Person <hello world>
[Client.cpp] end 
[Client.cpp] person1->name() = <no value>
[Client.cpp] person2->name() = Cendrine
[Client.cpp] person1->name() = Floriane
[Client.cpp] person2->name() = Marcelle
~Person Floriane
~Person Marcelle

c demo
/* File: Ratings.h
 * Interface to libRatings.so 1.0.
 *************************************/

/* Adds 'rating' to the set.
 *      rating: Each character adds 1 to the numeric rating
 *              Example: "" = 0, "*" = 1, "**" = 2, "wer " = 4.
 */
void addRating(char *rating);

/* Returns the number of ratings in the set.
 */
int ratings(void);

/* Returns the mean rating of the set.
 */
char *meanRating(void);

/* Clears the set.
 */
void clearRatings(void);


/* Ratings.h revision history
 * 1. First version of this file.
 */
/* File: Ratings.c
 * Compile with -fvisibility=hidden.                        // 1
 **********************************/

#include "Ratings.h"
#include <stdio.h>
#include <string.h>

#define EXPORT __attribute__((visibility("default")))
#define MAX_NUMBERS 99

static int _number_list[MAX_NUMBERS];
static int _numbers = 0;

// Initializer.
__attribute__((constructor))
static void initializer(void) {                             // 2
    printf("[%s] initializer()\n", __FILE__);
}

// Finalizer.
__attribute__((destructor))
static void finalizer(void) {                               // 3
    printf("[%s] finalizer()\n", __FILE__);
}

// Used by meanRating, middleRating, frequentRating.
static char* _char_rating(int rating) {
    char result[10] = "";
    int int_rating = rating;
    for (int i = 0; i < int_rating; i++) {
        strncat(result, "*", sizeof(result) - strlen(result) - 1);
    }
    return strdup(result);
}

// Used by addRating.
void _add(int number) {                                     // 4
    if (_numbers < MAX_NUMBERS) {
        _number_list[_numbers++] = number;
    }
}

// Used by meanRating.
int _mean(void) {
    int result = 0;
    if (_numbers) {
        int sum = 0;
        int i;
        for (i = 0; i < _numbers; i++) {
            sum += _number_list[i];
        }
        result = sum / _numbers;
    }
    return result;
}

EXPORT
void addRating(char *rating) {                              // 5
    if (rating != NULL) {
        int numeric_rating = 0;
        int pos = 0;
        while (*rating++ != '\0' && pos++ < 5) {
            numeric_rating++;
        }
        _add(numeric_rating);
    }
}

EXPORT
char* meanRating(void) {
    return _char_rating(_mean());
}

EXPORT
int ratings(void) {
    return _numbers;
}

EXPORT
void clearRatings(void) {
    _numbers = 0;
}


/* Ratings.c revision history
 * 1. First version.
 */
/* Runtime.c
 * Tests libRatings.so as a runtime loaded library.
 ***********************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>
#include <string.h>
#include "Ratings.h"

#define PASSFAIL "Passed":"Failed"
#define UNTST "Untested"

int main(int argc, char **argv) {
    printf("[start_test]\n");

    // Open the library.
    char *lib_name = "./libRatings.so";
    void *lib_handle = dlopen(lib_name, RTLD_NOW);
    if (lib_handle) {
        printf("[%s] dlopen(\"%s\", RTLD_NOW): Successful\n", __FILE__, lib_name);
    }
    else {
        printf("[%s] Unable to open library: %s\n",
            __FILE__, dlerror());
        exit(EXIT_FAILURE);
    }
    
    // Get the symbol addresses.
    void (*addRating)(char*) = dlsym(lib_handle, "addRating");
    if (addRating) {
        printf("[%s] dlsym(lib_handle, \"addRating\"): Successful\n", __FILE__);
    }
    else {
        printf("[%s] Unable to get symbol: %s\n",
            __FILE__, dlerror());
        exit(EXIT_FAILURE);
    }
    char* (*meanRating)(void) = dlsym(lib_handle, "meanRating");
    if (meanRating) {
        printf("[%s] dlsym(lib_handle, \"meanRating\"): Successful\n", __FILE__);
    }
    else {
        printf("[%s] Unable to get symbol: %s\n",
            __FILE__, dlerror());
        exit(EXIT_FAILURE);
    }
    void (*clearRatings)(void) = dlsym(lib_handle, "clearRatings");
    if (clearRatings) {
        printf("[%s] dlsym(lib_handle, \"clearRatings\"): Successful\n", __FILE__);
    }
    else {
        printf("[%s] Unable to get symbol: %s\n",
            __FILE__, dlerror());
        exit(EXIT_FAILURE);
    }
    int (*ratings)(void) = dlsym(lib_handle, "ratings");
    if (ratings) {
        printf("[%s] dlsym(lib_handle, \"ratings\"): Successful\n", __FILE__);
    }
    else {
        printf("[%s] Unable to get symbol: %s\n",
            __FILE__, dlerror());
        exit(EXIT_FAILURE);
    }
            
    // Setup.
    addRating(NULL);
    addRating("");
    addRating("*");
    addRating("**");
    addRating("***");
    addRating("*****");
    addRating("*****");
    
    // ratings.
    printf("[%s] ratings(): %s\n", __FILE__, (ratings() == 6? PASSFAIL));
    
    // meanRating.
    printf("[%s] meanRating(): %s\n", __FILE__, (strcmp(meanRating(), "**") == 0)? PASSFAIL);

    // clearRatings.
    clearRatings();
    printf("[%s] clearRatings(): %s\n", __FILE__, (ratings() == 0? PASSFAIL));

    // Close the library.
    if (dlclose(lib_handle) == 0) {
        printf("[%s] dlclose(lib_handle): Successful\n", __FILE__);
    }
    else {
        printf("[%s] Unable to open close: %s\n",
            __FILE__, dlerror());
    }

    printf("[end_test]\n");
    return 0;
}

/* Runtime.c revision history 
 * 1. First version.
 */
# File: makefile
# Image: libRatings.so 1.0
# Test applications: Dependent and Runtime.

all: dylib dependent runtime

dylib: Ratings.c Ratings.h
	gcc -shared -fPIC -fvisibility=hidden -o libRatings.so Ratings.c

dependent: Dependent.c dylib
	gcc -o Dependent Dependent.c ./libRatings.so	

runtime: Runtime.c
	gcc -o Runtime Runtime.c -ldl
	
clean:
	rm -f libRatings.so Dependent Runtime
./Runtime
[start_test]
[Ratings.c] initializer()
[Runtime.c] dlopen("./libRatings.so", RTLD_NOW): Successful
[Runtime.c] dlsym(lib_handle, "addRating"): Successful
[Runtime.c] dlsym(lib_handle, "meanRating"): Successful
[Runtime.c] dlsym(lib_handle, "clearRatings"): Successful
[Runtime.c] dlsym(lib_handle, "ratings"): Successful
[Runtime.c] ratings(): Passed
[Runtime.c] meanRating(): Passed
[Runtime.c] clearRatings(): Passed
[Ratings.c] finalizer()
[Runtime.c] dlclose(lib_handle): Successful
[end_test]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值