C++ Builder
| Главная | Уроки | Статьи | FAQ | Форум | Downloads | Литература | Ссылки | RXLib | Диски |

 
Работа с параметром типа char* в функции.
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 smile.gif должно помочь.
Asher
Отправлено: 13.07.2005, 09:36


Мастер участка

Группа: Модератор
Сообщений: 550



Не понимаю зачем нужны эти извращения если Admin в первом сообщении первым абзацем дал стандартое, универсальное и надежное решение.

Вернуться в Вопросы программирования в C++Builder