1:
libf1.so
#ifndef F1_HH_
#define F1_HH_
extern “C” int func1(char *p);
#endif
#include <iostream>
using namespace std;
#ifdef __cplusplus
extern "C" {
#endif
int func1(char *p)
{
if(p)
{
std::cout <<"func1: " ;
std::cout <<p << endl;
}
return 1;
}
#ifdef __cplusplus
}
#endif
libf2.so
類似, 隻是輸出不同
2: 編譯so
g++ f1.cpp -shared -fPIC -g -o libf1.so
g++ f2.cpp -shared -fPIC -g -o libf2.so
3: 應用程式
注冊信号、動态加載;收到信号後重新加載
幾個注意點:
a) so的編譯
b) #ifdef __cplusplus ; 防止找不到符号。 so的編譯器與應用程式的編譯器保持一緻
c) g++ -rdynamic -lf1 -g -o test main.cpp -ldl 編譯應用程式。 -lf1的意思是動态連結libf1.so -ldl是為了使得可以動态加載libf2.so
4) 應用程式使用的so必需是通過符号連結到真實的so檔案; 可以直接加載so,但是這種情況下so不能被修改(覆寫),覆寫時會程式core掉
[cpp] view plain copy
- #include <stdio.h>
- #include <stdlib.h>
- #include <dlfcn.h>
- #include <signal.h>
- #include <iostream>
- #include <errno.h>
- #include "f1.h"
- int isreload = 0;
- void sig_show(int s)
- {
- printf("catched signal: %d/n", s);
- return;
- }
- void sig_reloadso(int s)
- {
- printf("catched signal: %d/n", s);
- isreload = 1;
- printf("sigfunc isreload ? %d/n", isreload);
- return;
- }
- int main(int argc, char *argv [])
- {
- std::cout <<"main begin/n";
- struct sigaction show;
- show.sa_handler = &sig_show;
- show.sa_flags = SA_NOMASK;
- show.sa_restorer = 0;
- if(sigaction(3, &show, 0) == -1)
- {
- printf("sigaction failed. errno: %d/n", errno);
- return 0;
- }
- struct sigaction reload;
- reload.sa_handler = &sig_reloadso;
- reload.sa_flags = SA_NOMASK;
- reload.sa_restorer = 0;
- if(sigaction(4, &reload, 0) == -1)
- {
- printf("sigaction failed. errno: %d/n", errno);
- return 0;
- }
- void *libf2;
- int (*f2)(char *);
- const static char * h = "hello";
- char buf[200];
- if((libf2 = dlopen("./libf2.so", RTLD_NOW | RTLD_GLOBAL)) != 0)
- {
- f2 = (int (*)(char *)) dlsym(libf2, "func2");
- if(dlerror())
- {
- printf("error? %s/n", dlerror());
- }
- }
- else
- {
- printf("can not open libf2.so/n");
- return 0;
- }
- int i;
- while(1)
- {
- printf("isreload ? %d/n", isreload);
- if(isreload) //test if need reload
- {
- dlclose(libf2);
- if((libf2 = dlopen("./libf2.so", RTLD_LAZY | RTLD_GLOBAL)) != 0)
- {
- f2 = (int (*)(char *)) dlsym(libf2, "func2");
- if(dlerror())
- {
- printf("error? %s/n", dlerror());
- return 0;
- }
- }
- isreload = 0;
- printf("successfully reload libf2.so/n");
- }
- ++i;
- sprintf(buf, "%s %d", h, i);
- f2(buf); //from f2
- func1(buf); //from f1
- sleep(4);
- }
- return 0;
- }