38 / 1 / 0
Регистрация: 09.08.2012
Сообщений: 44

Как инициализировать массив в dll ?

08.06.2015, 11:59. Показов 2911. Ответов 30
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Экспериментирую с dll.
Сделал графическую функцию, которая рассчитывает расстояние между точками в цикле.
Хочу оптимизировать ее, чтоб не каждый раз квадратный корень вычислять, а брать результат из массива скажем 100х100.
Подскажите пожалуйста как объявить статический массив в dll ке и как инициализировать ее значениями, вызвать из проги какую-нибудь функцию инициализации или только через DllMain ?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
08.06.2015, 11:59
Ответы с готовыми решениями:

Как инициализировать массив чисел в С++?
Помогите пожалуйста, проблема следующая: в классе Eleve нужно инициализировать массив чисел (оценки) так, чтобы при создании класса он...

Как инициализировать такой массив
Нужно в проге(консольное приложение Win32) испоьзовать массив таких размеров double massiv_resultatov={0}; просто так я не смог его...

Как инициализировать массив переменной
Всем доброго времени суток! у меня возникла проблема, мне нужно инициализировать статический массив с помощью переменной, т.е. пользователь...

30
43 / 43 / 12
Регистрация: 06.10.2014
Сообщений: 135
08.06.2015, 12:27
Если значения известны во время компиляции, то инициализируйте массив как обычно, типа double arr[100][100] = {...}. Если значения не известны во время компиляции, то в DllMain. Что можно делать, а что нет в DllMain смотрите здесь Dynamic-Link Library Best Practices.
Тему в C++ и WinAPI нужно было размещать.
0
38 / 1 / 0
Регистрация: 09.08.2012
Сообщений: 44
08.06.2015, 12:35  [ТС]
Все разобрался сам.
В h файле все делаем.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
static int qwerty[10][10];
 
 
static bool vs_initialize(){
    for(int i=0;i<10;i++)
    {
        for(int j=0;j<10;j++)
        {
            qwerty[i][j] = (int)sqrt(float(i*i+j*j));
        }
    }
    return true;
};
из самой программы уже доступны результаты после ф-ции инициализации
C++
1
2
3
4
vs_initialize();
        cout <<"корень "<<qwerty[4][5]<<endl;
        cout <<"корень "<<qwerty[1][1]<<endl;
        cout <<"корень "<<qwerty[3][2]<<endl;
вот интересно в DLL будет ли это работать если ф-цию инициализации сделать доступной??
0
43 / 43 / 12
Регистрация: 06.10.2014
Сообщений: 135
08.06.2015, 12:45
Я вот смотрю, что значения можно посчитать зарание. Лучше сделать это (например, сохраните результаты в файл и скопируйте их). И инициализируйте массив статически, а не динамически.
C++
1
2
3
4
5
int qwerty[10][10] =
{
    {0, 1, ...},
    ...
};
Вызывать специально функцию инициализации не очень хорошо, если этого можно избежать.
1
38 / 1 / 0
Регистрация: 09.08.2012
Сообщений: 44
08.06.2015, 12:56  [ТС]
Мысль конечно здравая, но во первых там массив 300 на 300 будет, многовато текста.
Во вторых таких массивов нужно несколько, если вот только еще один отдельный файл с ними зафигачить.
И программу которая это все считает и пишет текст другой программы)) хм, что то в этом есть..
0
19471 / 10080 / 2456
Регистрация: 30.01.2014
Сообщений: 17,763
08.06.2015, 12:58
Цитата Сообщение от Denissimo Посмотреть сообщение
Все разобрался сам.
Неа, не разобрался. Если так делать, то массив будет НЕ в dll. static дает внутреннее связывание, этот массив будет определен в том файле, куда ты подключил h-ник (и в каждом таком cpp будет по своему массиву поэтому). Т.о., если в dll тоже есть свой cpp, который подключает этот h-ник, то там будет свой вариант этого массива, никак не связанный с тем, что в основной программе. С таким же успехом ты мог вообще не использовать dll, а сразу объвить глобальный массив в своей программе.

Denissimo, правильно делать так:
В h-файле dll
C++
1
2
3
4
5
6
7
8
9
// при компиляции dll определить PROJECT_EXPORTS глобально для проекта
#ifdef PROJECT_EXPORTS
    #define API __declspec(dllexport)
#else
    #define API __declspec(dllimport)
#endif
 
API extern int qwerty[10][10];
API extern "C" bool vs_initialize();
В cpp-файле dll
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <твой_h_файл_dll.h>
 
API int qwerty[10][10];
 
API bool vs_initialize() {
    for(int i=0;i<10;i++)
    {
        for(int j=0;j<10;j++)
        {
            qwerty[i][j] = (int)sqrt(float(i*i+j*j));
        }
    }
    return true;
}
2
 Аватар для Kastaneda
5232 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
08.06.2015, 13:04
можно при помощи метапрограммирования сделать, тогда массив будет заполняться во время компиляции, т.е. в рантаме не надо ничего отдельно вызывать.
1
38 / 1 / 0
Регистрация: 09.08.2012
Сообщений: 44
08.06.2015, 13:16  [ТС]
Неа, не разобрался.
Да, вы правы, спасибо. Дома попробую, тут только экспресс выпуск у меня.


можно при помощи метапрограммирования сделать
расскажите поподробнее пожалуйста, или если можно короткий пример, вот хоть на вышеприведенный код
0
 Аватар для Kastaneda
5232 / 3204 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
08.06.2015, 13:24
Цитата Сообщение от Denissimo Посмотреть сообщение
расскажите поподробнее пожалуйста, или если можно короткий пример
Вот пример заполнения массива в компайл тайм.
1
38 / 1 / 0
Регистрация: 09.08.2012
Сообщений: 44
08.06.2015, 13:53  [ТС]
Вот пример заполнения массива в компайл тайм.
я чет немного туплю, но не могу понять как для двумерного массива это вкорячить?
C++
1
2
3
4
5
6
7
8
9
10
11
template<size_t index> struct MetaFunc { 
    enum { value = index + 1 }; 
};
 
void test() {
    const size_t count = 5;
    typedef generate_array<count, MetaFunc>::result A;
 
    for (size_t i=0; i<count; ++i) 
        std::cout << A::data[i] << "\n";
}
еще один шаблон с функцией внутрь шаблона надо?
наверное слишком сложно.
0
43 / 43 / 12
Регистрация: 06.10.2014
Сообщений: 135
08.06.2015, 14:10
Цитата Сообщение от Denissimo Посмотреть сообщение
И программу которая это все считает и пишет текст другой программы)) хм, что то в этом есть..
Вы реально не поняли о чем я вам сказал? Для вас сложно записать форматированные результаты вычисления в файл? А потом скопировать и вставить?
0
38 / 1 / 0
Регистрация: 09.08.2012
Сообщений: 44
08.06.2015, 15:08  [ТС]
Вы реально не поняли о чем я вам сказал
нет нет все понятно, просто шутка юмора.
можно же не просто форматированные результаты в файл записать, добавить заголовки сразу и т.д.
Вариант вполне рабочий, я пока решил остановиться на варианте с инициализацией. А вам спасибо за помощь)
0
38 / 1 / 0
Регистрация: 09.08.2012
Сообщений: 44
10.06.2015, 08:58  [ТС]
Назрел новый вопрос. Может ктонибудь в курсе.
В DLL ке есть класс.
Чтоб он был доступен из основной программы что надо сделать?
extern "C" - перед конструктором?
перед каждой функцией?
целиком его вынести в хедер файл?
0
19471 / 10080 / 2456
Регистрация: 30.01.2014
Сообщений: 17,763
10.06.2015, 09:08
Цитата Сообщение от Denissimo Посмотреть сообщение
В DLL ке есть класс.
Чтоб он был доступен из основной программы что надо сделать?
Здесь
1
38 / 1 / 0
Регистрация: 09.08.2012
Сообщений: 44
10.06.2015, 09:47  [ТС]
Здесь
Ого! Какой классный сайт. Спасибо большое.

Добавлено через 21 минуту
Я правильно понял что DLL сделанная с использованием
C++
1
__declspec(dllexport)
может быть использована только с таким же компилятором?
0
19471 / 10080 / 2456
Регистрация: 30.01.2014
Сообщений: 17,763
10.06.2015, 10:11
Цитата Сообщение от Denissimo Посмотреть сообщение
может быть использована только с таким же компилятором?
Да. Это из-за этого. Касается не только dll.

Переносимы только вызовы в стиле С.
0
38 / 1 / 0
Регистрация: 09.08.2012
Сообщений: 44
10.06.2015, 10:19  [ТС]
Переносимы только вызовы в стиле С.
а если я так целый класс или отдельные ф-ции обозначу?
например -
C++
1
2
3
4
5
6
7
class AAA
{
public:
  extern "C" AAA();
  extern "C" ~AAA();
  void Func(int x);
}
будет работать?
0
19471 / 10080 / 2456
Регистрация: 30.01.2014
Сообщений: 17,763
10.06.2015, 10:34
Цитата Сообщение от Denissimo Посмотреть сообщение
будет работать?
Нет.
extern "C" - это не какая-то магия, это явное задание декорации имени для линкера в стиле С. Очевидно, что для классов это вообще не применимо, т.к. в С нет классов.
Если хочется сохранить совместимость, то от явного использования классов придется отказаться.
0
38 / 1 / 0
Регистрация: 09.08.2012
Сообщений: 44
10.06.2015, 10:51  [ТС]
Вот жеж блин.
Теперь понятно почему OpenCV содержит dll ки под разные компиляторы.
Это значит если я хочу чтоб моей библиотекой могли пользоваться люди на разных win32|64
и разных компиляторах- - надо под каждый вариант отдельно компилировать?
0
19471 / 10080 / 2456
Регистрация: 30.01.2014
Сообщений: 17,763
10.06.2015, 11:12
Цитата Сообщение от Denissimo Посмотреть сообщение
Это значит если я хочу чтоб моей библиотекой могли пользоваться люди на разных компиляторах- - надо под каждый вариант отдельно компилировать?
Не обязательно.
Можно сделать сишный интерфейс к библиотеке. А классы - это будут минимальные обертки над ним.
Примерно так:
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
28
29
30
31
32
33
34
35
36
// В хедере dll
struct MyClass;
 
extern "C" MyClass * create(void);
extern "C" void destroy(MyClass * ptr);
 
// далее каждый метод класса MyClass описываем по принципу
extern "C" void method1(MyClass * ptr /*указатель на экземпляр*/, int arg /*аргументы метода*/);
 
// В реализации dll (cpp)
 
struct MyClass
{
public:
   MyClass() { }
   ~MyClass() { }
 
   void method1(int arg) {  /*реализация метода*/ }
private:
   /// данные класса
};
 
// реализация экспортируемых функций. Сам класс НЕ экспортируется
extern "C" MyClass * create(void)
{
    return new MyClass();
}
extern "C" void destroy(MyClass * ptr)
{
    delete ptr;
}
 
extern "C" void method1(MyClass * ptr, int arg)
{
    ptr->method(arg);
}
Естественно никакого std::, никаких сложных типов из С++ в возвращаемых значениях и аргументов.
Теперь к dll мы делаем еще один заголовочник, у которого реализация будет чисто в нем и заключаться будет только в пробрасывании сишных вызовов обратно в С++ код.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class MyClassW
{
    struct MyClassDeleter 
    {
        void operator(MyClass * ptr) const
        {
             ::destroy(ptr);
        }
    };
 
public:
   MyClassW() : ptr_(::create()) 
   {}
   
   void method1(int arg)
   {
       ::method1(ptr_.get(), arg); 
   }  
 
private:
   std::unique_ptr<MyClass, MyClassDeleter> ptr_;
};
И пользоваться в клиентском С++ коде уже этой оберткой. Т.к. она полностью inline и занимается только прокидыванием вызовов в экспортируемые функции dll, то оверхеда не будет. Зато получим видимость того, что работаем с классом из dll, хотя код станет переносим между компиляторами.

Добавлено через 43 секунды
Писал прямо в окошке сообщения, так что могут быть опечатки. В любом случае - это псевдокод.

Добавлено через 1 минуту
Цитата Сообщение от Denissimo Посмотреть сообщение
на разных win32|64
А вот здесь уже сложнее. Здесь нужно будет таки делать две версии, по-хорошему.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
10.06.2015, 11:12
Помогаю со студенческими работами здесь

Как инициализировать массив в классе
private: static char const figury_={0,4,0,0, 0,1,0,3, 2,1,0,3, 0,2,0,2, 1,2,0,2, ...

Как инициализировать массив строк?
Здравствуйте, подскажите как инициализировать массив строк, кол-во строк неизвестно, они будут загружаться из текстового файла. И как...

Можно ли как-то инициализировать массив?
Можно ли как-то инициализировать массив ar? class digit { int a, b; public: digit (int a_, int b_) { a=a_; b=b_; }

Как инициализировать двумерный массив?
подскажите как инициализировать двумерный массив long long int mass;

Как инициализировать массив в структуре?
есть структура struct UtilPs2 { string arg; }; нужно её инициализировать чем можно заменить такое пошаговое заполнение?


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

Новые блоги и статьи
Как украсить новогоднюю елку с Q# и Qiskit
EggHead 24.06.2025
Что может быть необычнее, чем применить законы квантовой механики для украшения новогодней елки? Пока другие развешивают обычные гирлянды, я решил объединить свою страсть к квантовым вычислениям с. . .
Системы нулевого доверия на C#
UnmanagedCoder 24.06.2025
Традиционная архитектура безопасности работает по принципу средневекового замка: создаём высокие стены вокруг корпоративной сети, укрепляем ворота межсетевыми экранами и системами обнаружения. . .
Снова не мой путь. Циклическое среднее, я обеими руками за проверку условия, в ракурсе данной задачи - циклическое среднее в топку.
Hrethgir 24.06.2025
Привет. Такой вопрос - нужно выводить среднее математическое между двумя направлениями, интервал значений которых может лежать в диапазоне одного оборота по кругу. Проблема заключается в том, что. . .
Деплой Flask приложения
py-thonny 23.06.2025
За годы работы с Flask я натыкался на одни и те же грабли достаточно часто, чтобы наконец научится их обходить. И сегодня хочу поделится опытом, который сбережет вам немало нервных клеток. Начнем с. . .
WebAssembly и контейнеры в .NET Aspire для оркестрации распределенных архитектур
ArchitectMsa 23.06.2025
Я наблюдаю, как WebAssembly (или просто WASM) постепенно выходит за рамки своего первоначального предназначения — исполнения кода на стороне браузера. Теперь эта технология проникает в серверную. . .
Непрерывная интеграция для пакета Python
Mr. Docker 22.06.2025
Было 4 часа утра пятницы, когда я выпустил новую версию нашей внутренней библиотеки для обработки данных. Релиз 0. 5. 2 содержал небольшой фикс для обработки дат в ISO формате, что может пойти не так?. . .
Продвинутый ETL на C# из OLTP БД в хранилище
stackOverflow 22.06.2025
Работая в сфере корпоративной аналитики, я постоянно сталкиваюсь с одним и тем же - нужны чистые, структурированные и, главное, свежие данные. Без них современные аналитические системы, машинное. . .
Мастер-класс по микросервисам на Node.js
Reangularity 21.06.2025
Node. js стал одной из самых популярных платформ для микросервисной архитектуры не случайно. Его неблокирующая однопоточная модель и событийно-ориентированный подход делают его идеальным для. . .
Управление Arduino из WPF приложения
Wired 21.06.2025
Зачем вообще связывать Arduino с WPF-приложением? Казалось бы, у Arduino есть собственная среда разработки, своя экосистема, свои способы управления. Однако при создании серьезных проектов. . .
Звёздная пыль
kumehtar 20.06.2025
Я просто это себе представляю: как создавался этот мир. Как энергия слипалась в маленькие частички. Как они собирались в первые звёзды, как во вселенной впервые появился Свет. Как эти звёзды. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru