我的情况如下:我需要构建一个库,在这个库中导出一个“包装”strcpy (请忽略它对我有多大用处),它唯一能做的就是调用标准(从string.h) strcpy,但返回void,而不是返回char *。这意味着,我需要#include string.h,但这将立即给我strcpy和gcc不让我按我的意愿重新定义它,并且构建一个只导出新的包装的strcpy的.so共享库。我怎样才能做到这一点?
发布于 2020-04-12 15:26:58
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作为弱函数导出,您可以在库中重新定义它。
为了正确地链接您的.so,您必须禁用用于链接的标准库,并按照适当的顺序列出文件:strcpy内在.o,然后最终需要标准库和mystring.o .o。这将防止来自.so的递归strcpy调用。gcc的例子就像
gcc -shared -nostdlib -o my.so stringinternal.o -lc mystring.o发布于 2020-04-12 15:18:17
如果使用c++,则可以定义自己的命名空间,例如:
在没药里
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
}将链接您的.so的代码。你可以:
using namespace strcpy_v2;而不是
using namespace std;发布于 2020-04-12 15:42:29
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的头(正确的方式)。
https://stackoverflow.com/questions/61173514
复制相似问题