Sample code for dynamic libraries loadling a static library
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "common.h" | |
#include <cstdio> | |
#include <string> | |
static TCommonStruct GlobalStatic(0, "GlobalStatic"); | |
TCommonStruct* GetGlobalStatic() | |
{ | |
return &GlobalStatic; | |
} | |
TCommonStruct* GetFunctionStatic() | |
{ | |
static TCommonStruct FunctionStatic(1, "FunctionStatic"); | |
return &FunctionStatic; | |
} | |
TCommonStruct GlobalNonStatic(2, "GlobalNonStatic"); | |
TCommonStruct* GetGlobalNonStatic() | |
{ | |
return &GlobalNonStatic; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <string> | |
class TCommonStruct | |
{ | |
public: | |
int Mint; | |
std::string MString; | |
TCommonStruct(int i, std::string s) | |
: Mint(i), | |
MString(s) | |
{} | |
}; | |
TCommonStruct* GetGlobalStatic(); | |
TCommonStruct* GetFunctionStatic(); | |
TCommonStruct* GetGlobalNonStatic(); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "common.h" | |
#include <cstdio> | |
extern "C" { | |
TCommonStruct* Dynamic1GetGlobalStatic() | |
{ | |
TCommonStruct* t = GetGlobalStatic(); | |
::printf("%s: %p\n", __func__, t); | |
return t; | |
} | |
TCommonStruct* Dynamic1GetFunctionStatic() | |
{ | |
TCommonStruct* t = GetFunctionStatic(); | |
::printf("%s: %p\n", __func__, t); | |
return t; | |
} | |
TCommonStruct* Dynamic1GetGlobalNonStatic() | |
{ | |
TCommonStruct* t = GetGlobalNonStatic(); | |
::printf("%s: %p\n", __func__, t); | |
return t; | |
} | |
static int i = 1; | |
int GetInt() | |
{ | |
return i; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class TCommonStruct; | |
extern "C" { | |
TCommonStruct* Dynamic1GetGlobalStatic(); | |
TCommonStruct* Dynamic1GetFunctionStatic(); | |
TCommonStruct* Dynamic1GetGlobalNonStatic(); | |
int GetInt(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "common.h" | |
#include <cstdio> | |
extern "C" { | |
TCommonStruct* Dynamic2GetGlobalStatic() | |
{ | |
TCommonStruct* t = GetGlobalStatic(); | |
::printf("%s: %p\n", __func__, t); | |
return t; | |
} | |
TCommonStruct* Dynamic2GetFunctionStatic() | |
{ | |
TCommonStruct* t = GetFunctionStatic(); | |
::printf("%s: %p\n", __func__, t); | |
return t; | |
} | |
TCommonStruct* Dynamic2GetGlobalNonStatic() | |
{ | |
TCommonStruct* t = GetGlobalNonStatic(); | |
::printf("%s: %p\n", __func__, t); | |
return t; | |
} | |
static int i = 2; | |
int GetInt() | |
{ | |
return i; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class TCommonStruct; | |
extern "C" { | |
TCommonStruct* Dynamic2GetGlobalStatic(); | |
TCommonStruct* Dynamic2GetFunctionStatic(); | |
TCommonStruct* Dynamic2GetGlobalNonStatic(); | |
int GetInt(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This is the sample code for dynamic libraries loadling a static library, the behavior could be different with different compile/link options and dlopen() options. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "dynamic1.h" | |
#include "dynamic2.h" | |
#include <cstdio> | |
#include <cstdlib> | |
#include <dlfcn.h> | |
//#define DIRECT_CALL_SO | |
//#define USE_RTLD_GLOBAL | |
typedef TCommonStruct* (*FuncGetCommonStruct)(); | |
typedef int (*FuncGetInt)(); | |
#define CheckNotNull(p) \ | |
do {\ | |
if (p == NULL) {\ | |
char *errstr;\ | |
errstr = dlerror();\ | |
if (errstr != NULL) {\ | |
::printf("%s[%d] got NULL: %s\n", __func__, __LINE__, errstr);\ | |
}\ | |
else {\ | |
::printf("%s[%d] got NULL\n", __func__, __LINE__);\ | |
}\ | |
::abort();\ | |
}\ | |
}\ | |
while(0) | |
#ifndef DIRECT_CALL_SO | |
void TestLoadDynamic1() | |
{ | |
void* handle = ::dlopen("./libdynamic1.so", RTLD_LAZY | |
#ifdef USE_RTLD_GLOBAL | |
| RTLD_GLOBAL | |
#endif | |
); | |
CheckNotNull(handle); | |
FuncGetCommonStruct func; | |
func = reinterpret_cast<FuncGetCommonStruct>( | |
::dlsym(handle, "Dynamic1GetGlobalStatic")); | |
CheckNotNull(func); | |
func(); | |
func = reinterpret_cast<FuncGetCommonStruct>( | |
::dlsym(handle, "Dynamic1GetFunctionStatic")); | |
CheckNotNull(func); | |
func(); | |
func = reinterpret_cast<FuncGetCommonStruct>( | |
::dlsym(handle, "Dynamic1GetGlobalNonStatic")); | |
CheckNotNull(func); | |
func(); | |
FuncGetInt f = reinterpret_cast<FuncGetInt>( | |
::dlsym(handle, "GetInt")); | |
CheckNotNull(f); | |
::printf("GetInt returns %d\n", f()); | |
} | |
void TestLoadDynamic2() | |
{ | |
void* handle = ::dlopen("./libdynamic2.so", RTLD_LAZY | |
#ifdef USE_RTLD_GLOBAL | |
| RTLD_GLOBAL | |
#endif | |
); | |
CheckNotNull(handle); | |
FuncGetCommonStruct func; | |
func = reinterpret_cast<FuncGetCommonStruct>( | |
::dlsym(handle, "Dynamic2GetGlobalStatic")); | |
CheckNotNull(func); | |
func(); | |
func = reinterpret_cast<FuncGetCommonStruct>( | |
::dlsym(handle, "Dynamic2GetFunctionStatic")); | |
CheckNotNull(func); | |
func(); | |
func = reinterpret_cast<FuncGetCommonStruct>( | |
::dlsym(handle, "Dynamic2GetGlobalNonStatic")); | |
CheckNotNull(func); | |
func(); | |
FuncGetInt f = reinterpret_cast<FuncGetInt>( | |
::dlsym(handle, "GetInt")); | |
CheckNotNull(f); | |
::printf("GetInt returns %d\n", f()); | |
} | |
#endif | |
int main() | |
{ | |
#ifdef DIRECT_CALL_SO | |
Dynamic1GetGlobalStatic(); | |
Dynamic1GetFunctionStatic(); | |
Dynamic1GetGlobalNonStatic(); | |
::printf("GetInt returns %d\n", GetInt()); | |
Dynamic2GetGlobalStatic(); | |
Dynamic2GetFunctionStatic(); | |
Dynamic2GetGlobalNonStatic(); | |
::printf("GetInt returns %d\n", GetInt()); | |
#else | |
TestLoadDynamic1(); | |
TestLoadDynamic2(); | |
#endif | |
return 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CXX = g++ | |
AR = ar | |
RM = rm -f | |
CPPFLAGS = -g -Wall -Wextra | |
lib_target = libcommon.a | |
lib_srcs += common.cpp | |
so1_target = libdynamic1.so | |
so1_srcs += dynamic1.cpp | |
so2_target = libdynamic2.so | |
so2_srcs += dynamic2.cpp | |
main_srcs += main.cpp | |
srcs = $(lib_srcs) $(so1_srcs) $(so2_srcs) $(main_srcs) | |
so_objs = $(subst .cpp,.o,$(so1_srcs)) | |
so_objs += $(subst .cpp,.o,$(so2_srcs)) | |
LIB_TARGETS += $(lib_target) | |
SO_TARGETS += $(so1_target) $(so2_target) | |
.PHONY: clean run | |
all: main | |
main: $(LIB_TARGETS) $(SO_TARGETS) | |
g++ -o main $(main_srcs) -ldl | |
# g++ -DDIRECT_CALL_SO -o main $(main_srcs) -L. -ldynamic1 -ldynamic2 | |
$(LIB_TARGETS): common.o | |
$(AR) rcs $@ $^ | |
$(so1_target): | |
$(CXX) $(CPPFLAGS) -fPIC -shared -o $@ $(so1_srcs) -L. -lcommon | |
$(so2_target): | |
$(CXX) $(CPPFLAGS) -fPIC -shared -o $@ $(so2_srcs) -L. -lcommon | |
*.o: | |
$(CXX) $(CPPFLAGS) -o $@ $^ | |
clean: | |
$(RM) main *.o $(LIB_TARGETS) $(SO_TARGETS) | |
run: main | |
LD_LIBRARY_PATH=. ./main | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment