Экспорт символов под другим именем - PullRequest
0 голосов
/ 12 апреля 2020

Моя ситуация такова: мне нужно создать библиотеку, в которую я экспортирую «завернутый» strcpy (пожалуйста, не обращайте внимания, насколько это полезно для меня), который единственное, что он делает, это вызывает стандарт (из string.h) ) strcpy но верните void вместо возврата char *. Это означает, что мне нужно #include string.h, но это немедленно даст мне strcpy, а gcc не позволит мне переопределить его, как я sh, и создать общую библиотеку .so, экспортирующую только новую завернутый strcpy. Как я могу совершить это sh? 1011 *

Ответы [ 3 ]

2 голосов
/ 12 апреля 2020

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 вы должны отключить стандартные библиотеки для файлов связей и списков в правильном порядке: затем strcpyinternal.o потребуются стандартные libs и mystring.o в конце. Это предотвратит рекурсивный вызов strcpy из вашего .so. Пример для g cc может быть как

gcc -shared -nostdlib -o my.so stringinternal.o -lc mystring.o
1 голос
/ 12 апреля 2020

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

Для использования (основной. 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 (правильный путь).

0 голосов
/ 12 апреля 2020

Если вы используете 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

}

Из кода, который свяжет вас .so. Вы можете сделать:

using namespace strcpy_v2;

вместо

 using namespace std;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...