-Поиск по дневнику

Поиск сообщений в rss_forum_sources_ru

 -Подписка по e-mail

 

 -Постоянные читатели

 -Статистика

Статистика LiveInternet.ru: показано количество хитов и посетителей
Создан: 29.07.2007
Записей:
Комментариев:
Написано: 80


Библиотека на С++ для вызова библиотеки на С в Linux

Суббота, 19 Сентября 2020 г. 16:32 + в цитатник
ЫукпШ: Трудно сходу сказать, что у тебя не получается.
Легче сделать самому, а потом рассказать - как.
Только с ассемблером я не работаю, это ты сам делай.
1. Сделаем модуль на С и поместим его в статическую библиотеку:
    //---------------------------------------------------------------------------
    // file test.c 2020.09.19
    //---------------------------------------------------------------------------
    // gcc -c test.c
    // ar cr xxmm.a test.o
    //---------------------------------------------------------------------------
    #include
    //---------------------------------------------------------------------------
    int TypeTest (const char* pStr)
    {
    if(!pStr) return -1;
    printf ("function=%s pStr=%s\n",__FUNCTION__,pStr);
    return 0;
    }
    //---------------------------------------------------------------------------

------
Скомпилируем и добавим в статическую библиотеку xxmm.a:
gcc -c test.c
ar cr xxmm.a test.o
------
Напишем исходник .so и соберём его вместе с библиотекой xxmm.a:
    //---------------------------------------------------------------------------
    // file testdll.cpp 2020.09.19
    //---------------------------------------------------------------------------
    #include
    //---------------------------------------------------------------------------
    extern "C"
    {
    int DllTest (const char* pStr);
    int TypeTest (const char* pStr);
    //void _init() - будет вызвана при инициализации динамической библиотеки (загрузки ее в память);
    //int _init (void);
    //void _fini() - будет вызвана при выгрузке из памяти динамической библиотеки.
    //int _fini (void);
    }
    //---------------------------------------------------------------------------
    //export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:.
    //---------------------------------------------------------------------------
    /*
    int _init()
    {
    return iRetC;
    }
    */
    //---------------------------------------------------------------------------
    /*
    int _fini()
    {
    return iRetC;
    }
    */
    //---------------------------------------------------------------------------
    int DllTest(const char* pStr)
    {
    return TypeTest (pStr);
    }
    //---------------------------------------------------------------------------

------
сборка so:
g++ -c -fPIC testdll.cpp
g++ -D_REENTRANT -s -shared testdll.o xxmm.a -o testdll.so
------
Теперь сделаем тест, который испытает библиотеку:
    //---------------------------------------------------------------------------
    // file checkdll.cpp 2020.09.19
    //---------------------------------------------------------------------------
    #include
    #include
    //---------------------------------------------------------------------------
    typedef int (*pDllTest) (const char* pStr);
    //---------------------------------------------------------------------------
    int InstallSo (void);
    int UnInstallSo (void);
    int MainWork (int argc,char *argv[]);
    //---------------------------------------------------------------------------
    void* libHWND = NULL;
    pDllTest DllTest = NULL;
    //---------------------------------------------------------------------------
    // укажем текущую директорию для поиска динамической библиотеки: export LD_LIBRARY_PATH=.
    // или укажем полный путь к библиотеке
    const char* pDllLibName = "testdll.so"; // имя динамической библиотеки
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    int main(int argc,char *argv[])
    {
    printf("--- main (checkdll test) v1.0 2019.09.19 ---\n");
    int iRetLib = -1;
    int iRetC = -1;
    for(int i=0;i==0;++i,iRetC=0)
    {
    iRetLib = InstallSo(); if(iRetLib < 0) break;
    printf("Install .so - OK!\n");
    iRetC = MainWork(argc,argv); if(iRetC < 0) break;
    }
    UnInstallSo();
    return iRetC;
    }
    //---------------------------------------------------------------------------
    //---------------------------------------------------------------------------
    int InstallSo(void)
    {
    int iRetC = 1;
    for(int i=0;i==0;++i,iRetC=0)
    {
    //загрузка библиотеки
    libHWND = ::dlopen(pDllLibName, RTLD_LAZY);//RTLD_LAZY);RTLD_NOW);
    if(!libHWND) { printf("dlopen() error: %s\n", dlerror()); iRetC = -1; break; }
    //ищем в библиотеке требуемые процедуры
    DllTest = (pDllTest)::dlsym(libHWND, "DllTest");
    if(!DllTest) { printf("found DllTest error: %s\n", dlerror()); iRetC = -2; break; }
    }
    return iRetC;
    }
    //---------------------------------------------------------------------------
    int UnInstallSo(void)
    {
    int iRetC = 1;
    for(int i=0;i==0;++i,iRetC=0)
    {
    if(!libHWND) break;
    ::dlclose(libHWND);
    libHWND=NULL;
    }
    return iRetC;
    }
    //---------------------------------------------------------------------------
    int MainWork(int argc,char *argv[])
    {
    int iRetC=-1;
    if(DllTest)
    {
    iRetC = DllTest("MainWork");
    // iRetC = DllTest(NULL);
    printf("iRetC=%d\n",iRetC);
    }
    return iRetC;
    }
    //---------------------------------------------------------------------------

------
Сборка теста:
g++ -c checkdll.cpp
g++ -Wall -pipe -ldl -D_REENTRANT -s checkdll.o -o checkdll
------
Для удобства сделаем общий командный файл для сборки всего хозяйства:

gcc -c test.c
ar cr xxmm.a test.o
g++ -c -fPIC testdll.cpp
g++ -D_REENTRANT -s -shared testdll.o xxmm.a -o testdll.so
g++ -c checkdll.cpp
g++ -Wall -pipe -ldl -D_REENTRANT -s checkdll.o -o checkdll
------
У меня получилось.
------
Надо указать свою текущую директорию для поиска .so - библиотеки
перед запуском теста:
export LD_LIBRARY_PATH=.
Или в исходнике указать полный путь библиотеки.
------
Ещё удобный вариант:
1. Узнаём полное имя запущенного приложения.
2. Извлекаем из него path
3. Добавляем к path имя библиотеки, тем самым получая полное её имя в текущей директории.
4. Всё, она загрузится.

https://forum.sources.ru/index.php?showtopic=419682&view=findpost&p=3839099

Метки:  

 

Добавить комментарий:
Текст комментария: смайлики

Проверка орфографии: (найти ошибки)

Прикрепить картинку:

 Переводить URL в ссылку
 Подписаться на комментарии
 Подписать картинку