powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как динамически выделить память в DLL ?
20 сообщений из 20, страница 1 из 1
Как динамически выделить память в DLL ?
    #34922364
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть Win клиент на C++Builder.
Необходимо переслать двоичные данные на Linux сервер на Qt.
Двоичные данные перед отправкой необходимо сжать.

Поскольку на сервере разжимать их будет сервер средствами Qt, то и сжимать я решил средствами Qt.
Для этого написал Dll на Qt для Win.

Если память выделять malloc() и освобождать free() в клиенте, а в Dll подавать только указатель, то всё нормально работает.

Но это тестовый вариант.
В рабочем варианте заранее не известно сколько памяти нужно для буфера. (На оч. малом объёме размер сжатых будет больше чем не сжатых данных).

Но любые попытки выделить немного памяти в клиенте, а в Dll сделать realloc() до нужного размера - приводят к плачевным результатам.

Пробовал выделять память malloc() в Dll и потом очищать в клиенте - тоже всё плохо.


Вообще возможно выделять память в Dll динамически ? Может ключики какие компилятору сообщить нада ?
В Инете порылся ничего путного не нашёл.
...
Рейтинг: 0 / 0
Как динамически выделить память в DLL ?
    #34922410
egorych
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
сдаётся мне, что нельзя так жестоко поступать... память надо выделять и освобождать в одном месте - либо на клиенте, либо в dll.
...
Рейтинг: 0 / 0
Как динамически выделить память в DLL ?
    #34922528
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
egorychсдаётся мне, что нельзя так жестоко поступать... память надо выделять и освобождать в одном месте - либо на клиенте, либо в dll.

И я об этом. Где нагадил там и вычищай!

Но единтсвенный работающий вариант на сейчас(now) это так:

1. Завести в DLL глобальный буфер.
2. Внутри DLL функция qCompress его заполнила и вернула размер
3. На клиенте выделить память этого размера
4. Вторая функция DLL взяв указатель от клиента, копирует содержимое этого буфера
5. Клиент освобождает память, когда уже не нужна.

Но теперь меня смущает наличие глобальной переменной в DLL.
Т.е. если юзер запустит несколько экземпляров клиентской части, что они получат из DLL ?
Т.е. не будет ли конфликтов ?
...
Рейтинг: 0 / 0
Как динамически выделить память в DLL ?
    #34922701
vlad-p
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Зачем так сложно?

В dll 2 функции
1-я. Сжать что дали и вернуть указатель на сжатое
2-я. Взять указатель от вызова 1-й и освободить

клиент
дернул первую функцию, поработал с возвращенным буфером, дернул вторую - освободил буфер.
...
Рейтинг: 0 / 0
Как динамически выделить память в DLL ?
    #34922914
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZmeisheНо теперь меня смущает наличие глобальной переменной в DLL.
Т.е. если юзер запустит несколько экземпляров клиентской части, что они получат из DLL ?
Т.е. не будет ли конфликтов ?Нет, конфликтов не будет. Каждый процесс который делает LoadLibrary заводит в том числе и новую копию глобальных переменных объявленных в DLL.
...
Рейтинг: 0 / 0
Как динамически выделить память в DLL ?
    #34922955
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White OwlНет, конфликтов не будет. Каждый процесс который делает LoadLibrary заводит в том числе и новую копию глобальных переменных объявленных в DLL.

Спа!
...
Рейтинг: 0 / 0
Как динамически выделить память в DLL ?
    #34923308
smskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выделять память в DLL можно, но и освобождать память можно только в этой же DLL. Правило такое - освобождать память можно только в том модуле, в котором ты его создал.
...
Рейтинг: 0 / 0
Как динамически выделить память в DLL ?
    #34923310
smskin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
То есть я хотел сказать:
smskinВыделять память в DLL можно, но и освобождать память можно только в этой же DLL. Правило такое - освобождать память можно только в том модуле, в котором ты её выделил.
...
Рейтинг: 0 / 0
Как динамически выделить память в DLL ?
    #34923491
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
smskinВыделять память в DLL можно, но и освобождать память можно только в этой же DLL. Правило такое - освобождать память можно только в том модуле, в котором ты её выделил.Это не совсем правда. Можно и в разных, никаких препятствий тут нету.
Но если взять себе за правило освобождать в том же модуле в котором выделил, то жить будет проще.
...
Рейтинг: 0 / 0
Как динамически выделить память в DLL ?
    #34923685
teras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
White Owl wrote:
>> smskin
>> Выделять память в DLL можно, но и освобождать память можно только в этой
>> же DLL. Правило такое - освобождать память можно только в том модуле, в
>> котором ты её выделил.
>
> Это не совсем правда. Можно и в разных, никаких препятствий тут нету.
> Но если взять себе за правило освобождать в том же модуле в котором
> выделил, то жить будет проще.

Лучше сказать так - это вполне возможно, и зависит от компилятора и от
режима компиляции. Например, в MSVCRT от VS6 отдельный хип (похоже, что
и в VS2005 - тоже). И если слинковать dll со статической библиотекой
(LIBC, LIBCMT), а exe - с MSVCRT (или две разных dll, слинкованные со
статической библиотекой), то нельзя смешивать malloc/free, функции,
работающие с FILE* и т.п.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Как динамически выделить память в DLL ?
    #34925130
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
smskin пишет:
> Выделять память в DLL можно, но и освобождать память можно только в этой
> же DLL. Правило такое - освобождать память можно только в том модуле, в
> котором ты его создал.

Это неправда. Выделять и освобождать память можно (и нужно иногда ) в любом
исполняемом модуле данного процесса. Нужно только чтобы соблюдалось одно
условие - менеджер памяти, с помощью которого память выделяется, и
менеджен памяти, с помощью которого она освобождается, должны быть одним и
тем же менеджером памяти. Возможна даже ситуация, когда в приложении (процессе)
одновременно используются несколько менеджеров памяти. Это нормальная ситуация
и ничего плохого тут нет.
В Win32 это вообще типичная ситуация - каждое приложение на С/С++ как правило
использует два менеджера памяти - из стандартной библиотеки С и из Win32.
А может быть оно еще использует и свои менеджеры.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Как динамически выделить память в DLL ?
    #34925138
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
White Owl пишет:
> Это не совсем правда. Можно и в разных, никаких препятствий тут нету.

Это - СОВСЕМ НЕПРАВДА, а не "не совсем правда".

> Но если взять себе за правило освобождать в том же модуле в котором
> выделил, то жить будет проще.

Это может быть вообще невозможно в каких-то приложениях.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Как динамически выделить память в DLL ?
    #34925152
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe пишет:

Вообще возможно выделять память в Dll динамически ? Может ключики какие
> компилятору сообщить нада ?

Можно. Прото ты наверное используешь в каких-то DLL статическую CRTL.
Если ты используешь DLL-и и выделяешь и удаляешь память в разных
выполняемых модулях, то у тебя для этих модулей должен быть один и тот
же C-шный рантайм (менеджер памяти). Т.е. в данном случае ты должен
использовать реализацию CRTL в виде .DLL, а не статическую. Во всех модулях.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Как динамически выделить память в DLL ?
    #34927713
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv
Прото ты наверное используешь в каких-то DLL статическую CRTL.

Если честно - я не знаю чего там используется.
Я весь софт перевожу под Linux. С БД и сервером приложений уже закончил.
Клиента так быстро не могу.
Для этого в Win клиентском приложении на C++Builder создал своих наследников от TCustomRemoteServer и от TClientDataSet.
Но сжимать/разжимать данные на Builder так чтобы понимал сервер, который на Qt не получилось.
Сделал проще - сваял на Qt под win dll-ку, а из bpl её вызываю через LoadLibrary - всё Ok.
Но выделять память в dll, а очищать в bpl не получилось. Вернее два раза получилось на на третий всё - АБЗАЦ.

MasterZivу тебя для этих модулей должен быть один и тот
же C-шный рантайм (менеджер памяти). Вот теперь понимаю почему вышел АБЗАЦ.
BPL - сделана компилятором Borland
DLL - сделана компилятором MinGW
Нутром чую - у них разные менеджеры памяти.
...
Рейтинг: 0 / 0
Как динамически выделить память в DLL ?
    #34928252
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe пишет:

> Если честно - я не знаю чего там используется.

Это плохо, ты ДОЛЖЕН это знать.

> Вот теперь понимаю почему вышел АБЗАЦ.
> BPL - сделана компилятором Borland
> DLL - сделана компилятором MinGW
> Нутром чую - у них разные менеджеры памяти.

Наверняка.

Тут еще можно попробовать сделать такое.
Во всех приличных С-шных библиотеках, которые пользуются
динамической памятью, полагается иметь возможность
задавать функции распределения памяти, которые используются.
Поищи, может есть они в твоих проблемных библиотеках.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Как динамически выделить память в DLL ?
    #34928509
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivПоищи, может есть они в твоих проблемных библиотеках.
Смысла нет так глубоко копать.
Я решил проблему добавлением глобальной переменной.
1-я функция делает zip и скидывает его в этот глобальный буфер, а на клиента возвращает размер.
Клиент выделяет память и во вторую функцию подаёт указатель, чтоб забрать содержимое буфера.
Вот код DLL:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
#include <qdatastream>

QByteArray block;



extern "C" __declspec(dllexport) int Compress(const uchar *inBuf, int inBytes)	
{
    block = qCompress(inBuf, inBytes);
    return block.size();
};

extern "C" __declspec(dllexport) int Uncompress(const uchar *inBuf, int inBytes)	
{
    block = qUncompress(inBuf, inBytes);
    return block.size();
};

extern "C" __declspec(dllexport) void GetZipUnzipData(char* outBuf)	
{
    QDataStream out(&block, QIODevice::ReadOnly);
    out.readRawData(outBuf, block.size());
};

Вот код в BPL
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
MyClass::MyClass()
{
   LoadLibrary(...);
}

void MyClass::Any_Out(TMemoryStream *Stream)
{
  int outSize = Compress((UCHAR*) Stream->Memory, Stream->Size);
  
  char *outBuf = (char*) malloc(outSize);
  
  GetZipUnzipData(outBuf);
  
  socket_stream->Write(outBuf, outSize);

  free(outBuf);
}
И всех делов.
Меня только смущала глобальная переменная в DLL. Поэтому я пытался выделить память в функциях Compress/Uncompress, а освобождать в BPL.
...
Рейтинг: 0 / 0
Как динамически выделить память в DLL ?
    #34929092
teras
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Zmeishe wrote:

> Автор: "Zmeishe"
> MasterZiv
> Поищи, может есть они в твоих проблемных библиотеках.
>
>
> Смысла нет так глубоко копать.
> Я решил проблему добавлением глобальной переменной.
> 1-я функция делает zip и скидывает его в этот глобальный буфер, а на
> клиента возвращает размер.
> Клиент выделяет память и во вторую функцию подаёт указатель, чтоб
> забрать содержимое буфера.

Обычной способ решения - это сделать в той же DLL функцию, освобождающую
память обратно. Например:

DLL:
Код: plaintext
\n/* Конечно, объявление datum должно быть в головном файле.\n * На всякий сучай - не надо возвращать структуру в качестве\n * результата, наподобие такого\n * \tdatum fun();\n * это непереносимо между компиляторами.\n */\n\nstruct datum\n{\n\tvoid * ptr;\n\tsize_t size;\n};\n\nstatic int\nexport_data(datum * out, const QByteArray& block)\n{\n    int csize = block.size();\n    out->size = csize;\n    out->ptr = malloc(csize);\n\n    QDataStream outstm(&block, QIODevice::ReadOnly);\n    outstm.readRawData(out->ptr, csize);\n    return csize;\n}\n\nextern "C" __declspec(dllexport)\nint Compress(datum* out, const uchar *inBuf, int inBytes)\t\n{\n    return export_data(out, qCompress(inBuf, inBytes));\n}\n\nextern "C" __declspec(dllexport)\nint Uncompress(const uchar *inBuf, int inBytes)\t\n{\n    return export_data(out, qUncompress((inBuf, inBytes));\n}\n\nextern "C" __declspec(dllexport)\nint FreeDatum(datum* datum)\n{\n    free(datum->ptr);\n    datum->ptr = NULL;\n} 

Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Как динамически выделить память в DLL ?
    #34933130
Фотография cap83
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не выделяйте память маллоком пользуйте апишные функции ...... А то можно с такими делами столкнуться
...
Рейтинг: 0 / 0
Как динамически выделить память в DLL ?
    #34935095
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
cap83 пишет:
> Не выделяйте память маллоком пользуйте апишные функции ...... А то можно
> с такими делами столкнуться

Это вовсе не обязательно.
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Как динамически выделить память в DLL ?
    #34935896
Фотография cap83
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если dll с другим crt собрана будет
...
Рейтинг: 0 / 0
20 сообщений из 20, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Как динамически выделить память в DLL ?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]