以不同名称导出符号
Exporting symbols under a different name
我的情况如下:我需要建立一个库,导出一个 "wrapped" strcpy
(请忽略这对我有什么用),它唯一做的就是调用标准(来自 string.h
)strcpy
但 return void
,而不是 returning char *
。这意味着,我需要 #include string.h
但这会立即给我 strcpy
并且 gcc
不会让我按照我的意愿重新定义它,并构建一个 .so
共享库仅导出新的、包装的 strcpy
。我怎样才能做到这一点?
如果你使用c++,你可以定义你自己的命名空间例如:
在 my.h
namespace strcpy_v2
{
void strcpy( char *dest, const char *src );
}
在关联的my.cpp
#include <string>
#include "my.h"
void strcpy_v2::strcpy( char *dest, const char *src )
{
auto val = std::strcpy(dest,src);
// you should test val to ensure every thing is ok
}
来自 link 您的代码。你可以这样做:
using namespace strcpy_v2;
而不是
using namespace std;
mystring.h
extern "C" void strcpy(char* dst, const char* src);
stringinternal.h
void mystrcpy(char* dst, const char* src);
mystring.c
#include "mystring.h"
#include "stringinternal.h"
extern "C" void strcpy(char* dst, const char* src) {
mystrcpy(dst, src);
}
stringinternal.c
#include "stringinternal.h"
#include <string.h>
void mystrcpy(char* dst, const char* src) {
strcpy(dst, src);
}
main.c
#include "mystring.h"
int main() {
char dst[3];
strcpy(dst, "ab");
return 0;
}
标准 strcpy
导出为弱函数,您可以在您的库中重新定义它。
为了正确 link 你的 .so 你必须禁用 linkage 的标准库并以正确的顺序列出文件:strcpyinternal.o 然后需要标准库和 mystring.o 到底。这将防止来自您的 .so 的递归 strcpy 调用。 gcc 的示例可以是
gcc -shared -nostdlib -o my.so stringinternal.o -lc mystring.o
strcpy
是带有 "C" 链接的弱符号,因此可以无错误地覆盖
libstrcpy.cc:
#include <dlfcn.h>
extern "C" {
void strcpy(char *dest, char *src)
{
auto real_strcpy = (char*(*)(char*,char*)) dlsym(RTLD_NEXT, "strcpy");
real_strcpy(dest, src);
}
}
编译:g++ libstrcpy.cc -std=c++11 -shared -fPIC -ldl -o libstrcpy.so
验证 strcpy
导出:readelf --dyn-syms libstrcpy.so
要使用 (main.cc):
extern "C"{
void strcpy(char *, char *);
}
int main()
{
char a[10] = "test" , b[10] = {};
strcpy(a, b);
}
编译为:g++ main.cc -o main -lstrcpy -L./
请注意,如果您想使用正确的 void
返回声明,则不能导入任何将定义 strcpy
(正确方式)的 header。
我的情况如下:我需要建立一个库,导出一个 "wrapped" strcpy
(请忽略这对我有什么用),它唯一做的就是调用标准(来自 string.h
)strcpy
但 return void
,而不是 returning char *
。这意味着,我需要 #include string.h
但这会立即给我 strcpy
并且 gcc
不会让我按照我的意愿重新定义它,并构建一个 .so
共享库仅导出新的、包装的 strcpy
。我怎样才能做到这一点?
如果你使用c++,你可以定义你自己的命名空间例如:
在 my.h
namespace strcpy_v2
{
void strcpy( char *dest, const char *src );
}
在关联的my.cpp
#include <string>
#include "my.h"
void strcpy_v2::strcpy( char *dest, const char *src )
{
auto val = std::strcpy(dest,src);
// you should test val to ensure every thing is ok
}
来自 link 您的代码。你可以这样做:
using namespace strcpy_v2;
而不是
using namespace std;
mystring.h
extern "C" void strcpy(char* dst, const char* src);
stringinternal.h
void mystrcpy(char* dst, const char* src);
mystring.c
#include "mystring.h"
#include "stringinternal.h"
extern "C" void strcpy(char* dst, const char* src) {
mystrcpy(dst, src);
}
stringinternal.c
#include "stringinternal.h"
#include <string.h>
void mystrcpy(char* dst, const char* src) {
strcpy(dst, src);
}
main.c
#include "mystring.h"
int main() {
char dst[3];
strcpy(dst, "ab");
return 0;
}
标准 strcpy
导出为弱函数,您可以在您的库中重新定义它。
为了正确 link 你的 .so 你必须禁用 linkage 的标准库并以正确的顺序列出文件:strcpyinternal.o 然后需要标准库和 mystring.o 到底。这将防止来自您的 .so 的递归 strcpy 调用。 gcc 的示例可以是
gcc -shared -nostdlib -o my.so stringinternal.o -lc mystring.o
strcpy
是带有 "C" 链接的弱符号,因此可以无错误地覆盖
libstrcpy.cc:
#include <dlfcn.h>
extern "C" {
void strcpy(char *dest, char *src)
{
auto real_strcpy = (char*(*)(char*,char*)) dlsym(RTLD_NEXT, "strcpy");
real_strcpy(dest, src);
}
}
编译:g++ libstrcpy.cc -std=c++11 -shared -fPIC -ldl -o libstrcpy.so
验证 strcpy
导出:readelf --dyn-syms libstrcpy.so
要使用 (main.cc):
extern "C"{
void strcpy(char *, char *);
}
int main()
{
char a[10] = "test" , b[10] = {};
strcpy(a, b);
}
编译为:g++ main.cc -o main -lstrcpy -L./
请注意,如果您想使用正确的 void
返回声明,则不能导入任何将定义 strcpy
(正确方式)的 header。