Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Операционные системы > Linux (Ubuntu, Debian, Red Hat, CentOS, Mint)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.04.2018, 23:55   #1
Alexis_777
Пользователь
 
Регистрация: 08.11.2017
Сообщений: 48
По умолчанию Неопределённый символ в динамической библиотеке

При запуске исполняемого файла с динамической библиотекой позднего связывания вылазит ошибка:
Код:
./dynamic2.out: symbol lookup error: /usr/lib/lib_MYDYNAMIC.so: undefined symbol: _ZNSt12experimental10filesystem2v16statusERKNS1_4pathE
Как можно исправить?
extern "C" везде указаны, т.к. сборка на С++.
Alexis_777 вне форума Ответить с цитированием
Старый 24.04.2018, 07:39   #2
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Цитата:
Сообщение от Alexis_777 Посмотреть сообщение
Как можно исправить?
Почитать хоть какую-то теорию.

Цитата:
Сообщение от Alexis_777 Посмотреть сообщение
extern "C" везде указаны, т.к. сборка на С++.
А функция на С++ и с классами.
p51x вне форума Ответить с цитированием
Старый 24.04.2018, 11:58   #3
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

Импортировать чужое с extern "C" можно только, если они экспортируют так же. Иначе вы должны у себя просто extern писать и использовать тот же самый компилер. Ну в линукс оно так и есть - вся система собирается тем же самым. Связано с тем, что никак стандарта на все те буквочки нету толком (они кодируют однозначно прототип С++).

Последний раз редактировалось alexzk; 24.04.2018 в 12:01.
alexzk вне форума Ответить с цитированием
Старый 24.04.2018, 17:45   #4
Alexis_777
Пользователь
 
Регистрация: 08.11.2017
Сообщений: 48
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
Почитать хоть какую-то теорию.


А функция на С++ и с классами.
Читал и делал всё как положено. Функция с классами.
Alexis_777 вне форума Ответить с цитированием
Старый 24.04.2018, 17:46   #5
Alexis_777
Пользователь
 
Регистрация: 08.11.2017
Сообщений: 48
По умолчанию

Цитата:
Сообщение от alexzk Посмотреть сообщение
Импортировать чужое с extern "C" можно только, если они экспортируют так же. Иначе вы должны у себя просто extern писать и использовать тот же самый компилер. Ну в линукс оно так и есть - вся система собирается тем же самым. Связано с тем, что никак стандарта на все те буквочки нету толком (они кодируют однозначно прототип С++).
А если я использовал методы для С++, которых нету в Си, как тогда быть?
Alexis_777 вне форума Ответить с цитированием
Старый 24.04.2018, 17:52   #6
Alexis_777
Пользователь
 
Регистрация: 08.11.2017
Сообщений: 48
По умолчанию

Вот код программы:
Код:
#include <dlfcn.h>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>
#include <experimental/filesystem>
 
namespace fs = std::experimental::filesystem;
extern "C" void reverseFile(fs::path pfile1, fs::path const& pfile2);
extern "C" fs::path newPath(fs::path const& oldPth, fs::path const& pd1, fs::path const& pd2);
extern "C" void fullReverse(fs::path& pd1, fs::path& pd2);
 
int main()
{
    fs::path pd1("/home/student/dir1"); // каталог с исходными файлами
    fs::path pd2("/home/student/dir2"); // каталог с инвертированными файлами
    void *dl_handle;
    void(*func)(fs::path&, fs::path&);
 
    /* Открываем совместно используемую библиотеку */
    dl_handle = dlopen("lib_MYDYNAMIC.so", RTLD_LAZY);
 
    /* Находим адрес функции в библиотеке */
    func = (void(*)(fs::path&, fs::path&)) dlsym(dl_handle, "fullReverse");
 
    /* Вызываем функцию по найденному адресу и печатаем результат */
    (*func)(pd1, pd2);
 
    /* Закрываем объект */
    dlclose(dl_handle);
}
Вот сама библиотека:
Код:
#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
 
 
extern "C" void reverseFile(fs::path pfile1, fs::path const& pfile2)
{
    std::fstream ifs(pfile1, std::ios::in | std::ios::binary), ofs(pfile2, std::ios::out | std::ios::binary);
    if (ifs.is_open() && ofs.is_open())
    {
        ifs.seekg(0, ifs.end);
        if (ifs.tellg() >= std::streampos(1))
        {
            for (ifs.seekg(-1, ifs.cur); ; ifs.seekg(-2, ifs.cur))
            {
                ofs.put(ifs.get());
                if (ifs.tellg() == std::streampos(1))
                {
                    break;
                }
            }
        }
    }
    else
    {
        std::cerr << "Unable to open file(s): " << pfile1 << "  " << pfile2 << "\n\n";
    }
    ifs.close();
    ofs.close();
}
 
// создаём путь папки в каталоге с инвертированными файлами
extern "C" fs::path newPath(fs::path const& oldPth, fs::path const& pd1, fs::path const& pd2)
{
    fs::path ret = pd2;
    auto pr = std::mismatch(oldPth.begin(), oldPth.end(), pd1.begin(), pd1.end());
 
    for (auto ib(pr.first), ie(oldPth.end()); ib != ie; ++ib)
    {
        ret /= *ib;
    }
 
    return ret;
}
 
extern "C" void fullReverse(fs::path& pd1, fs::path& pd2)
{
    try
    {
        if (!fs::exists(pd2))
        {
            fs::create_directories(pd2); // может кинуть исключение
        }
        for (fs::recursive_directory_iterator ib(pd1), ie; ib != ie; ++ib) // перебираем все файлы в dir 1
        {
            if (fs::is_regular_file(ib->path())) // инвертируем каждый файл 
            {
                reverseFile(ib->path(), newPath(ib->path(), pd1, pd2));
            }
            else if (fs::is_directory(ib->path())) // создаём папку в каталоге с инвертированными файлами
            {
                fs::create_directory(newPath(ib->path(), pd1, pd2));
            }
        }
 
    }
    catch (std::exception const& exc)
    {
        std::cerr << "Exception: " << exc.what() << std::endl;
    }
}
Alexis_777 вне форума Ответить с цитированием
Старый 24.04.2018, 19:25   #7
p51x
Старожил
 
Регистрация: 15.02.2010
Сообщений: 15,695
По умолчанию

Цитата:
Сообщение от Alexis_777 Посмотреть сообщение
А если я использовал методы для С++, которых нету в Си, как тогда быть?
1. Использовать указатели, как делали в оле и интерфейсах. Их размер известен.
2. Полностью перейти на С++ или С.
3. Самому разбирать манглинг функции и грузить.
p51x вне форума Ответить с цитированием
Старый 24.04.2018, 22:22   #8
Alexis_777
Пользователь
 
Регистрация: 08.11.2017
Сообщений: 48
По умолчанию

Цитата:
Сообщение от p51x Посмотреть сообщение
1. Использовать указатели, как делали в оле и интерфейсах. Их размер известен.
2. Полностью перейти на С++ или С.
3. Самому разбирать манглинг функции и грузить.
Мне нужно передавать параметры в функции через указатели? Я правильно понял? А можно по ошибке понять на какой конкретно участок кода ругается?
Alexis_777 вне форума Ответить с цитированием
Старый 25.04.2018, 02:18   #9
Alexis_777
Пользователь
 
Регистрация: 08.11.2017
Сообщений: 48
По умолчанию

Проблему решил
Цитата:
Сообщение от p51x Посмотреть сообщение
3. Самому разбирать манглинг функции и грузить.
В функции fullReverse не так как нужно передавал параметры.
Alexis_777 вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Класс в динамической библиотеке fees Помощь студентам 0 17.10.2012 20:28
неопределённый размер строки типа char _KUL Общие вопросы C/C++ 4 16.05.2012 19:54
Assembler!!! Заменить на символ ‘!’ каждый 3тий символ в строке. Leon9313 Помощь студентам 0 24.04.2012 13:02
вопрос по библиотеке JIeka Общие вопросы C/C++ 8 26.08.2011 18:19
В библиотеке Mika_32 Паскаль, Turbo Pascal, PascalABC.NET 2 04.04.2010 19:00