Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.60/25: Рейтинг темы: голосов - 25, средняя оценка - 4.60
0 / 0 / 0
Регистрация: 04.07.2013
Сообщений: 17
1

Dll без внешних зависимостей?

05.08.2015, 17:23. Показов 4692. Ответов 20
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день,
Волею судьбы приходится писать программы для C++Builder XE8. К несчастью, библиотеки для работы с матрицами (решения уравнения вида Ax = b) подключить в эту "чудесную во всех отношениях" среду разработки не удается.
Я написал небольшой класс в VisualStudio и пытаюсь собрать из него библиотеку, чтобы избежать вышеописанной проблемы. Однако, разобраться как же все же нужно собирать библиотеки чтением гайдов и форумов не получилось.

Заголовочный файл моего класса:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <vector>
#include <cstdlib>
#include <Eigen/Dense>
 
namespace MyFun{
    class IV_curve{
    private:
        std::vector < double > I;
        std::vector < double > U;
        Eigen::Vector3d P = { 1.5, 1e-5, 1e-2 };            // Parameters
    public:
        __declspec(dllexport) void set(double x, double y);
        __declspec(dllexport) double NextStep(double goal);
        __declspec(dllexport) double fun(double tmp_I);
        __declspec(dllexport) void Jacobi(Eigen::Matrix3d *A);
        __declspec(dllexport) void RP(Eigen::Vector3d *b);
        __declspec(dllexport) double dPhi(int i, int k);
        __declspec(dllexport) void initial(double n, double I0, double R);
    };
}
Если создавать dll, ей все равно нужен заголовочный файл. А С++Builder не в состоянии использовать
C++
1
#include <Eigen/Dense>
библиотеку (она не поддерживает их компилятор, да и не только с этой библиотекой проблемы)

Подскажите пожалуйста, можно ли собрать либу из класса так, чтобы никие сторонние библиотеки не требовались? Поскольку, лишь в этом случае удастся использовать класс в C++Builder XE8/

Спасибо.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.08.2015, 17:23
Ответы с готовыми решениями:

Проверка зависимостей DLL
Гружу через LoadLibrary какую либо dll. Через GetLastError() проверяю код ошибки. Есть код...

Компиляция без зависимостей
Добрый день, хотел переписать программу с c# на с++ из-за вечного: там установлен .Net framework...

Доступ к переменным в DLL программе из внешних програм
Подскажите пожалуйста, как реализовать Записать данные из программы №1 в программу DLL и считать...

Класс без конструктора. Ошибка 1 неразрешенных внешних элементов
Добрый вечер. Помогите исправить ошибку. Пример у Страуструпа не работает. При компиляции...

20
9 / 9 / 0
Регистрация: 26.01.2015
Сообщений: 94
06.08.2015, 11:50 2
Киньте кусок кода в котором вы свою Dll подключаете.
0
0 / 0 / 0
Регистрация: 04.07.2013
Сообщений: 17
06.08.2015, 13:27  [ТС] 3
Я ее не подключаю, поскольку так и не разобрался в том, как собрать либу включив в нее
C++
1
#include <Eigen/Dense>
так чтобы в С++Buildere (в основном проекте куда я подключаю dll) функции этого инклуда не использовали.
0
9 / 9 / 0
Регистрация: 26.01.2015
Сообщений: 94
06.08.2015, 15:04 4
Вы точно установили весь SDK включая .h и .lib файлы?
0
0 / 0 / 0
Регистрация: 04.07.2013
Сообщений: 17
06.08.2015, 15:09  [ТС] 5
C++
1
#include <Eigen/Dense>
это сторонняя либа, а проблема в ее использовании заключается в не поддерживаемом компиляторе.
0
267 / 170 / 40
Регистрация: 25.08.2014
Сообщений: 1,087
Записей в блоге: 1
06.08.2015, 15:13 6
Цитата Сообщение от MitrandirSergey Посмотреть сообщение
#include <Eigen/Dense>
Цитата Сообщение от MitrandirSergey Посмотреть сообщение
библиотеку
Чо? #include включает содержимое указанного файла. Ты проверь, есть ли такой файл по указанному пути.
0
0 / 0 / 0
Регистрация: 04.07.2013
Сообщений: 17
06.08.2015, 15:20  [ТС] 7
Он есть, я указал путь к нему в настройках проекта, но компилятор не может это скомпилировать. В самой библиотеке есть строка в которой написано, что этот компилятор не поддерживается (нужно вручную указать некоторое значение). И на этом вся работа программы заканчивается.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
06.08.2015, 15:34 8
Цитата Сообщение от MitrandirSergey Посмотреть сообщение
Подскажите пожалуйста, можно ли собрать либу из класса так, чтобы никие сторонние библиотеки не требовались? Поскольку, лишь в этом случае удастся использовать класс в C++Builder XE8/
Насколько я знаю не удастся в любом случае, экспорт классов из DLL непереносимая шутка (между разными компиляторами) сам по себе,
C++Builder тут не причем.

Хотите переносимости - экпортируйте функции (не классы) в стиле Си (Си типы,без структур идр составных типов в параметрах, без декорирования тобишь extern "C")
И естественно это убьет все удобство при экспорте.

И как вариант поискать библиотеки для работы с матрицами написанные для Delphi/С++Builder
0
0 / 0 / 0
Регистрация: 04.07.2013
Сообщений: 17
06.08.2015, 15:45  [ТС] 9
То есть, вариант с собрать статическую либу в которую запихнуть
C++
1
#include <Eigen/Dense>
не прокатит вообще никак (сделав хидер в котором про эту стороннюю либу не упоминается)?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <vector>
#include <cstdlib>
 
 
namespace MyFun{
    class IV_curve{
    private:
        std::vector < double > I;
        std::vector < double > U;
        double n = 1.5;
        double I0 = 1e-5; // log(I0) actually
        double R = 1e-2;
    public:
        __declspec(dllexport) void set(double x, double y);
        __declspec(dllexport) double NextStep(double goal);
    };
}
Я попробовал другую либу и с ней тоже облом (С++Builder не полностью С++11 стандарт поддерживает, похоже).
Да и ко всему прочему, нужна совместимость C++Builder XE2 - C++Builder XE8 + у Embercadero (разработчиков C++Builder есть партнеры, которые нечто для научных сотрудников и инженеров развивают (работу с матрицами, решение уравнений) однако это все платное по)
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
06.08.2015, 16:03 10
Цитата Сообщение от MitrandirSergey Посмотреть сообщение
То есть, вариант с собрать статическую либу в которую запихнуть
Cтатичесую тем более.

Добавлено через 1 минуту
Цитата Сообщение от MitrandirSergey Посмотреть сообщение
(С++Builder не полностью С++11 стандарт поддерживает, похоже).
Это за висит от разрядности компилятора x32 -старый компилятор он практически не поддерживает стандарт.
a x64 новый с ним не должно быт проблем.

Добавлено через 45 секунд
Цитата Сообщение от MitrandirSergey Посмотреть сообщение
однако это все платное по)
Ну так и сама среда С++Bulder платная....
0
267 / 170 / 40
Регистрация: 25.08.2014
Сообщений: 1,087
Записей в блоге: 1
06.08.2015, 16:04 11
Цитата Сообщение от MitrandirSergey Посмотреть сообщение
я указал путь к нему в настройках проекта
Содержимое файла включается не настройками проекта, а директивой include.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
06.08.2015, 16:07 12
MitrandirSergey

Кстати а FMX не подходит:

http://docwiki.embarcadero.com... s.Vector3D
http://docwiki.embarcadero.com... D.Matrix3D
0
0 / 0 / 0
Регистрация: 04.07.2013
Сообщений: 17
06.08.2015, 16:21  [ТС] 13
К сожалению нет, поскольку могут понадобиться вектора произвольной длины (а здесь похоже только ). И решение уравнения вида Ax = b.
Но это отличная идея, вдруг у них для делфи есть соответствующие либы портированные в С++.
Спасибо. Поищу внимательнее.

По поводу компилятора, мне нужен именно x32 из за совместимости со строй средой. Печаль.

Среда платная, но в фирме, в которой я работаю, не захотят покупать что либо в дополнение к уже купленной одной версии C++Borland XE2.

Добавлено через 5 минут
Я безусловно подключаю либу используя #include и все файлы на месте, поскольку я указал их месторасположение. Весь вопрос в том, а можно ли целую стороннюю либу запихнуть в собственноручно сделанную либу и забыть про ее подключение в основной проект. В котором меня интересуют только две функции (из методов этого класса)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <vector>
#include <cstdlib>
 
 
namespace MyFun{
    class IV_curve{
    private:
        std::vector < double > I;
        std::vector < double > U;
        double n = 1.5;
        double I0 = 1e-5; // log(I0) actually
        double R = 1e-2;
    public:
        __declspec(dllexport) void set(double x, double y);
        __declspec(dllexport) double NextStep(double goal);
    };
}
P.S. либу я собрал из класса, но подключить ее в тестовый проект не удается (ошибка линковщика LNK2019) ...
не понятен тогда смысл создавать свои либы, если нельзя реализовать нечто подобное (использовать одну - две функции сторонней либы, не подключая стороннюю либу в проект).
(Я не программист)
0
18844 / 9843 / 2408
Регистрация: 30.01.2014
Сообщений: 17,285
06.08.2015, 18:37 14
Лучший ответ Сообщение было отмечено MitrandirSergey как решение

Решение

Цитата Сообщение от MitrandirSergey Посмотреть сообщение
не понятен тогда смысл создавать свои либы, если нельзя реализовать нечто подобное (использовать одну - две функции сторонней либы, не подключая стороннюю либу в проект).
Можно, но для этого в интерфейсе нужно отвязаться от типов, которые предлагает эта стороняя либа, заменив их переносимыми и совместимыми с С обертками.
Для экспорта из библиотеки использовать С-функции. Если нужны сложные объекты с состоянием (т.е. объекты классов), то в интерфейсе их описывать не нужно, вместо этого нужно возвращать "дескрипторы" (да хоть бы void*) таких объектов. Т.е. нужно будет выполнить сокрытие типов реализации за С-совместимым интерфейсом.
Покажу на простом примере, например есть класс А, с состоянием state. Нам нужно реализовать (по каким-то не зависящим от нас причинам) этот класс в Visual Studio, но использовать его надо в Builder XE.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// A.h
#ifndef A_H_INCLUDED
#define A_H_INCLUDED
 
namespace mylib 
{
 
class A
{
public:
    A() : state_(0) {}
 
    void incState(int x) { state_ += x; }
    int getState() const { return state_; }
 
private:
    int state_;
};
 
}
 
#endif
Этот класс не нужно засовывать в заголовочный файл, который будет поставлять c dll. Это внутренняя кухня.
В h-файле, который будет подключаться в другую среду, опишем такой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// dll_interface.h
#ifndef DLL_INTERFACE_H_INCLUDED
#define DLL_INTERFACE_H_INCLUDED
 
#ifdef ADLL_EXPORTS
#define ADLL_API __declspec(dllexport)
#else
#define ADLL_API __declspec(dllimport)
#endif
 
typedef void * ADescr;
 
#ifdef __cplusplus
extern "C" {
#endif
 
ADLL_API ADescr makeA(); // 
ADLL_API void releaseA(ADescr a);
 
ADLL_API void incState(ADescr a, int x);
ADLL_API int getState(ADescr a);
 
#ifdef __cplusplus
}
#endif
 
#endif // DLL_INTERFACE_H_INCLUDED
Это наш совместимый интерфейс. Именно им будет пользоваться Builder XE.
Реализация у него такая:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//dll_interface.cpp
#include "dll_interface.h"
#include "A.h"
 
ADescr makeA()
{
    return new(std::nothrow) mylib::A();
}
void releaseA(ADescr a)
{
    delete static_cast<mylib::A *>(a);
}
 
void incState(ADescr a, int x)
{
    static_cast<mylib::A *>(a)->incState(x);
}
 
int getState(ADescr a)
{
    return static_cast<mylib::A *>(a)->getState();
}
Теперь, чтобы пользователь класса А на стороне Builder XE не мучился с С-функциями, можно дописать в интерфейсный h-файл следующий код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#ifdef __cplusplus
 
class A
{
public:
    A() : descr_(::makeA())  { }
    ~A() { ::releaseA(descr_); }
 
    void incState(int x) 
    { 
        ::incState(descr_, x);
    }
    int getState() const
    {
        return ::getState(descr_);
    }
private:
    ADescr descr_;
 
    // Для простоты не стану делать класс копируемым, но если это нужно
    // то в С-интерфейсе нужно будет предусмотреть соответствующие функции
    A(A const &);
    A & operator=(A const &);
};
 
#endif
Таким образом, у нас во внутреннем классе А могут использоваться разные библиотеки, но их не будет видно снаружи dll. Если постараться организовать функции так, чтобы как можно меньше сложных данных переходило через границу dll, скажем, только входные данные для расчетов и рассчитанные выходные данные, то мы даже почти не потеряем в скорости работы. Естественно, лучше не усложнять себе жизнь и подумать каким образом организовать код так, чтобы типы библиотеки Eigen вообще не передавались через границу dll (т.е. чтобы не писать и для них обертки тоже). Т.е. если нужно заполнить их некими значениями, то можно передать их в виде массивов С + размерность, а внутри dll уже создастся какой-нибудь Eigen::Vector3d и заполнится переданными значениями из массива.
1
9 / 9 / 0
Регистрация: 26.01.2015
Сообщений: 94
06.08.2015, 20:06 15
void incState(int x) { state_ += x; }
int getState() const { return state_; }
DrOffset, что значит const?
0
Avazart
06.08.2015, 20:21
  #16

Не по теме:

Цитата Сообщение от Licoze Посмотреть сообщение
DrOffset, что значит const?
Приехали ...

0
DrOffset
06.08.2015, 20:45
  #17

Не по теме:

Цитата Сообщение от Licoze Посмотреть сообщение
что значит const?
Если коротко, то обозначает, что функция не меняет состояние класса.
Const в функциях-членах класса
Могут ли быть указаны квалификаторы типа в качестве возвращаемого значения функции/метода?
Можно еще поискать по форуму. Тем таких полно было. Повторяться нет смысла.

0
0 / 0 / 0
Регистрация: 04.07.2013
Сообщений: 17
07.08.2015, 14:18  [ТС] 18
Большое спасибо!
0
9 / 9 / 0
Регистрация: 26.01.2015
Сообщений: 94
07.08.2015, 19:12 19
Avazart, DrOffset, Да я просто больше по шарпу, а для чего при объявлении чисто вирт. функции пишут то void func()=0; то void func() const =0;?если не сложно, а то я как-то гуглил да не выгуглил.
0
0 / 0 / 0
Регистрация: 01.08.2015
Сообщений: 32
07.08.2015, 19:25 20
MitrandirSergey,

Советую использовать библиотеку Intel MKL: она сразу обновляется при появлении новых процессоров: например, у меня два шестиядерных процессора - один haswell, а второй - поддерживает только команды SSE (вплоть до самых последних). Первый перемножает две матрицы 10000*10000 за 7 с., а второй - более чем за 29 сек. Частоты обоих процессоров одинаковы (3.33 GHz).
0
07.08.2015, 19:25
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.08.2015, 19:25
Помогаю со студенческими работами здесь

Windows I/o без Kernel32.dll и Advapi32.dll
Добрый день. Необходимо в Windows XP SP3 распечатать в стандартный поток &quot;some text here&quot; без...

Архивация без использование внешних Dll
нужен компонент или способ для выполнениня ахивации из программы которая состоит из одного ЕХЕ...

C# без зависимостей
Как сделать, чтобы программа на c# запускалась без доп. зависимостей на windows от 7 до 10? ...

Сборка qt без зависимостей
Собирал по этому мануалу, но в каталоге bin не появились необходимые dll. Сборка завершилась...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru