dvv |
Отправлено: 09.07.2005, 19:03 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 43
|
У меня есть функция. Если схематично:
CODE |
AnsiString eng(char* CmdLine, char* Parametrs)
{
AnsiString Par=AnsiString(Parametrs);
. . .
}
|
С некоторых пор я переписал программу и у меня получилось:
CODE |
AnsiString eng(char* CmdLine, char* Parametrs)
{
AnsiString Par=AnsiString(Parametrs);
. . .
Par=Par+"возможно чего-то добавляется, и неизвестно сколько символов";
. . .
}
|
Проблема в том как теперь мне вернуть значение Par через параметр Parametrs? Ведь Parametrs это указатель на область памяти, в которой расположена строка, которая короче возвращаемой строки.
Очень не хотелось бы менять тип паремта Parametrs, поскольку функция eng находится в DLL и вызывается из многих программ. |
|
Admin |
Отправлено: 09.07.2005, 22:55 |
|
Владимир
Группа: Администратор
Сообщений: 1190
|
Поскольку память под строку выделяется в основной программе
(вызывающей из dll функцию eng) и вы передаете
лишь указатель char* Parametrs, возьмите и сразу выделите под эту
строку максимально возможное количество символов.
А чтобы не выйти и за этот размер — вставьте проверку в dll
перед добавлением в строку данных — на превышение этого размера.
Или добавьте в функцию третий параметр — то что добавляется -
char* addParametrs и выделяйте память под него в dll
|
|
dvv |
Отправлено: 10.07.2005, 19:36 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 43
|
QUOTE (Admin @ 09/07/2005, 22:55) | А чтобы не выйти и за этот размер — вставьте проверку в dll
перед добавлением в строку данных — на превышение этого размера.
|
За идею спасибо.
QUOTE (Admin @ 09/07/2005, 22:55) | Или добавьте в функцию третий параметр — то что добавляется -
char* addParametrs и выделяйте память под него в dll |
Тут я не совсем понял. Т.е функция примет вид:
CODE | AnsiString eng(char* CmdLine, char* Parametrs,char* addParametrs) |
Если я буду выделять память например так:
CODE | addParametrs=new char[100]; |
то значение указателя addParametrs сразу изменится. И та строка которая будет записана по адресу addParametrs из dll в основную программу не вернется. |
|
esh |
Отправлено: 11.07.2005, 00:05 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 71
|
Можно сделать так:
CODE | AnsiString eng(char* CmdLine, char* Parametrs,char **addParametrs)
{
...
*addParametrs=new char[100];
...
} |
Вот пример:
CODE | void f(char **str)
{
*str=new char[100];
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
char *str;
f(&str);
delete[] str;
} |
Можно использовать HeapAlloc, HeapReAlloc, HeapFree, тогда можно обойтись двумя параметрами, функции описаны в MSDN. |
|
FataLL |
Отправлено: 11.07.2005, 03:54 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 37
|
Вообще проблему не вижу. Присваивая значение указателю мы же не копируем туда строку. Зачем эти гиморрои с выделением памяти?
|
|
Asher |
Отправлено: 11.07.2005, 08:43 |
|
Мастер участка
Группа: Модератор
Сообщений: 550
|
Привет.
QUOTE | Вообще проблему не вижу. Присваивая значение указателю мы же не копируем туда строку. Зачем эти гиморрои с выделением памяти? |
Ну...
во 1-х нужно старый блок памяти освободить и где взять размер блока
во 2-х нужно решить кто будет новый блок удалять, и откуда он узнает размер блока.
Учитывая, что приложениеи DLL имеют, в общем случае, каждая свой менеджер памяти, то выделение блока в программе и освобождение его в DLL и наоборот 100% приводит к AV.
1. Или собирать их с общим менеджером памяти
2. или только передавать указатель на заранее подготовленный буфер и его размер и не перераспередять его ни в коем случае.
1-е не всегда возможно.
|
|
FataLL |
Отправлено: 13.07.2005, 00:57 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 37
|
Ну, пусть в DLL будет вся музыка, конечно. Самый простой вариант — это запастись строкой достаточной длины. Можно делать дубль передаваемой переменной в основной программе (чтоб освободить блок) и возвращать внутренний буфер, удаление и создание которого лежит на DLL. А вообще, можно воспользоваться перегрузкой и создать для новых приложений функцию дополнительным параметром для возврата.
|
|
esh |
Отправлено: 13.07.2005, 03:59 |
|
Дежурный стрелочник
Группа: Участник
Сообщений: 71
|
QUOTE | Учитывая, что приложениеи DLL имеют, в общем случае, каждая свой менеджер памяти, то выделение блока в программе и освобождение его в DLL и наоборот 100% приводит к AV. |
В HeapAllo, HeapReAlloc и HeapFree есть замечательный параметр HANDLE hHeap должно помочь.
|
|
Asher |
Отправлено: 13.07.2005, 09:36 |
|
Мастер участка
Группа: Модератор
Сообщений: 550
|
Не понимаю зачем нужны эти извращения если Admin в первом сообщении первым абзацем дал стандартое, универсальное и надежное решение.
|
|