Форум: "Прочее";
Текущий архив: 2011.07.24;
Скачать: [xml.tar.bz2];
ВнизДайте по рукам Найти похожие ветки
← →
test_test (2011-03-24 10:44) [0]Здрасти! Делаю dll на C++ и сильно хочу, чтоб эта длл выделяла и есно освобождала память для "клиента". Делаю так.
либа
/////////////////////////////////
extern "C"
{
typedef char *pchar;
void creatememchar (pchar& asd)
{
asd = new char [100000000];
}
void freememchar (pchar& asd)
{
delete[] asd;
}
}
/////////////////////////////////////
Клиент
////////////////////////////////
procedure creatememchar (var asd:PChar); cdecl external "libtest.dll";
procedure freememchar (var asd:PChar); cdecl external "libtest.dll";
procedure TForm1.Button1Click(Sender: TObject);
var
arr:PChar;
begin
creatememchar(arr);
freememchar(arr);
end;
где-то так.
Вопрос: насколько больно можно получить по рукам за такое или нормально? И куда выделяется память в этом случае. Думается мне что в кучу, так как у самой проги прироста используемое памяти не наблюдается, хотя массив вроде как работает нормально...
← →
Rouse_ © (2011-03-24 10:49) [1]new вызывает HeapAlloc, работать будет, только лучше все-же заставлять программу самостоятельно выделять память указывая ей требуемый размер.
← →
RWolf © (2011-03-24 10:51) [2]
> Вопрос: насколько больно можно получить по рукам за такое
> или нормально?
нормально, в принципе.
> И куда выделяется память в этом случае
В кучу, но не в дельфовскую, а в сишную — приложение и DLL собраны с разными менеджерами памяти
← →
test_test (2011-03-24 10:55) [3]аха понятно, пасиб
> только лучше все-же заставлять программу самостоятельно
> выделять память указывая ей требуемый размер.
Так и сделанно у меня сейчас, но хочется внутренне-ддэльные глобальные буффера вынести в наружу (этакие слои), так как планируется использовать "перекрестное" использование функционала
← →
han_malign (2011-03-24 11:33) [4]
> Вопрос: насколько больно можно получить по рукам за такое или нормально?
- заSysAllocString
/SysFreeString
из oleaut32.dll - что-то никто по рукам не получал... И есть еще куча API с функциями возвращающими ссылки на "внутреннюю" память которую потом надо освобождать XxxFree() (например LsaFreeMemory)...
Мода наHGLOBAL
безвозвратно ушла, хотя до сих пор встречается...
> new вызывает HeapAlloc
- не перекрытыйnew
вызываетmalloc
, который - если у вас MS VC и и определен символWINHEAP
- таки является оберткойHeapAlloc
, но в общем случае - это не всегда правда...
← →
test_test (2011-04-06 09:48) [5]
> но хочется внутренне-ддэльные глобальные буффера вынести
> в наружу (этакие слои)
мх, а если эти самые глобальные буффера сделанны так?vector <TSuper_puper_struct> puper_struct;
как на это указатель получить, а главное как потом с этим работать?
////Прога
var
asd:PChar;
procedure creatememchar (var asd:PChar); cdecl external "libtest.dll";
//// Либа
void creatememchar (pchar& asd)
{
Как тут эту самую asd привести к vector <TSuper_puper_struct>?
}
Все дело в том что эти буффера работают по принципу "накопления" памяти (это для ускорения процесса), тоесть при первой итерации выделил определенный кусок и при следующих с этим работает, если нужно больше добавляет... Можно было бы использовать new, но каждый раз перераспределять память... тогда и смысла небудет в глобальных.
← →
Romkin © (2011-04-06 10:51) [6]
> Все дело в том что эти буффера работают по принципу "накопления"
> памяти (это для ускорения процесса), тоесть при первой итерации
> выделил определенный кусок и при следующих с этим работает,
> если нужно больше добавляет... Можно было бы использовать
> new, но каждый раз перераспределять память... тогда и смысла
> небудет в глобальных.
Каждый раз распределяй памяти на четверть больше, чем сейчас выделено.
← →
test_test (2011-04-06 11:30) [7]выделенно 0, сколько потребуется выделить неизвестно. Объемы памяти выделяется порядочные. Потому первая итерация довольно медленная, а потому и глобальный буффер, чтоб следущии итерации были быстрее, гораздо быстрее. Пример. Если при первой итерации где-то 150-200 тиков, то при следующих 12-13. Но все это обламывает "перекрестное" использование функционала. Например
vector <int> arr;
void function1 (int i)
{
здесь заполняем arr значением i;
}
void function2 (pchar& value)
{
Здесь заполняем value значениями из arr и возвращаем вызов в прогу
}
Тоесть если я в проге вызову эти функции
так
function1(10);
function2
function1(20);
function2
то впринципе все ок
но если так
function1(10);
function1(20);
function2
function2
То потеряются значения для 10.
Потому и хочется сделать
function1(arr1,10);
function1(arr2,20);
function2(arr1)
function2(arr2)
где arr1,arr2 указатель на vector <int> arr;
← →
KSergey © (2011-04-06 11:33) [8]> test_test (06.04.11 09:48) [5]
> мх, а если эти самые глобальные буффера сделанны так?
>
> vector <TSuper_puper_struct> puper_struct;
>
> как на это указатель получить, а главное как потом с этим работать?
Это нативные вещи для каждого языка, в интерфейс такое выставлять нельзя. Так же, например, как array дельфовый. Ну т.е. выставить можно, но придется разобраться как он устроен и сделать соотв. обертку для его использования в другом языке, что некрасиво. Проце сразу объявить все таким образом, чтобы оно прозрачно перекладывалось на любой другой язык.
В принципе, вектор - это по идее линейный кусок памяти, фактически можно сказать, что если получить указатель на первый элемент уже распределенного массива, то дальше можно работать как с такой конструкцией:
TSuper_puper_struct *vector_Super_puper_struct;
ну или тоже самое
TSuper_puper_struct vector_Super_puper_struct[];
Т.е. можно в дельфи описать TSuper_puper_struct и указатель на нее, далее бегать по элементам этого вектора, только еще передать текущий размер вектора дополнительно. Не забывать, что при добавлении элементов вектора его адрес может измениться.
Но лучше сразу описать
TSuper_puper_struct *vector_Super_puper_struct;
под нее выделять память и указатель передавать. Это будет прозрачнее для всех.
← →
KSergey © (2011-04-06 11:35) [9]> Потому и хочется сделать
И кто запрещает? религия?
← →
test_test (2011-04-06 11:39) [10]
> TSuper_puper_struct *vector_Super_puper_struct;под нее выделять
> память и указатель передавать. Это будет прозрачнее для
> всех.
да но при добавлении к такому массиву элимента, нужно будет заново перераспредилить память и переписать занчения из уже существующего. чтоб совсем нехотелось.
PS. В программе, на каком языке она бы небыла написана, никто с этим буффером работать не будет. Прога будет проста хранить указатель на область памяти где этот вектор расположен и все. Работать с этим вектром будет сама длл
← →
KSergey © (2011-04-06 12:39) [11]> test_test (06.04.11 11:39) [10]
> да но при добавлении к такому массиву элимента, нужно будет заново перераспредилить память и переписать занчения из уже существующего.
1) realloc сделает это волшебно и прозрачно (выделение новой памяти и копирование имеющихся элементов с освобождением статорого куска).
2) а вы думаете при добавлении элементов в вектор все происходит как-то иначе? ровно так же.
Главное тут - перераспределять не на каждый элемент, а добавлять сразу большими кусками, как писалось выше.
Т.е. в дополнение к указателю хранить 2 целочисленные переменные: количество элементов, под которые выделена память сейчас и количество заполненных элементов. Опять же, класс вектор делает все ровно тоже самое! посмотрите реализацию его методов добавления элементов, ведь код STL доступен.
← →
test_test (2011-04-06 16:55) [12]
> Главное тут - перераспределять не на каждый элемент, а добавлять
> сразу большими кусками, как писалось выше.
Зацените функцию. На сколько все страшно?void Resize_arr1 (char *data,int count,int indexcase)
{
switch (indexcase)
{
case 1:
{
#define ppp PPointFloat_arr
#define tpp TPointFloat
}
break;
case 2:
{
#define ppp PGettingLinePoints_Arr
#define tpp TGettingLinePoints
}
break;
default:;
}
if (count<1)
{
if(ppp(data)->MaxSize>0) delete[] ppp(data)->data;
ppp(data)->MaxSize=0;
ppp(data)->Size=0;
} else
{
if (count<=ppp(data)->MaxSize)
{
ppp(data)->Size=count;
} else
{
ppp(data)->Size=count;
if (ppp(data)->MaxSize=0)
{
ppp(data)->MaxSize=count+100;
ppp(data)->data=new tpp [ppp(data)->MaxSize];
} else
{
tpp* fdata;
fdata =new tpp [ppp(data)->MaxSize];
for (int x =0;x<=ppp(data)->MaxSize-1;++x)
{
fdata[x]=ppp(data)->data[x];
}
delete[] ppp(data)->data;
ppp(data)->data = new tpp [count+100];
for (int x =0;x<=ppp(data)->MaxSize-1;++x)
{
ppp(data)->data[x]=fdata[x];
}
delete[] fdata;
ppp(data)->MaxSize=count+100;
}
}
}
}
← →
test_test (2011-04-06 17:01) [13]ай-ай
где if (ppp(data)->MaxSize=0) читать как if (ppp(data)->MaxSize==0)
← →
Inovet © (2011-04-06 17:39) [14]> [12] test_test (06.04.11 16:55)
> case 1:
> {
> #define ppp PPointFloat_arr
> #define tpp TPointFloat
> }
> break;
> case 2:
Так эта... в рантайм никаких #define уже не будет, их уже не будет даже во время компиляции. И операторные скобки тут лишние и не помогут.
> if (ppp(data)->MaxSize==0)
Некоторые делают такif (0 == ppp(data)->MaxSize)
чтобы при такомif (0 = ppp(data)->MaxSize)
ошибка была, а не присвоение, хоть и некрасиво. Но компилятор в твоём случае должен бы предупреждение выдать.
← →
test_test (2011-04-07 07:11) [15]
>switch (indexcase)
> {
>
> case 1:
> {
> #define ppp PPointFloat_arr
> #define tpp TPointFloat
> }
> break;
> case 2:
> {
> #define ppp PGettingLinePoints_Arr
> #define tpp TGettingLinePoints
> }
> break;
> default:;
> }
> Так эта... в рантайм никаких #define уже не будет, их уже
> не будет даже во время компиляции. И операторные скобки
> тут лишние и не помогут.
Да похоже на то. Только по счастливой случайности это все у меня не упало.
А реально ли повторить подобную конструкцию, но кашерно. Не хочется что-то плодить кучу функций с одним и тем же функционалом?
← →
KSergey © (2011-04-07 08:42) [16]> test_test (06.04.11 16:55) [12]
> Зацените функцию. На сколько все страшно?
Это пипец по многим причинам.
Одно не понятно: нафига все это?!
Не хочется что-то плодить кучу функций с одним и тем же функционалом?
Тогда шаблоны спасут.
ну и для затравки.. не знаю..
ну отсюда начните что ли
http://www.rsdn.ru/forum/cpp/784382.flat.aspx
Вообще - все это смысла не имеет, если С++ для вас - так, побаловаться. Потому как тама идеология сильно другая. Проще пользоваться STL-шаблонами, в них очень много нюансов уже толковыми человеками продумано (что касается, например, исключений в конструкторах или при выделении памяти - важно ведь суметь не потерять кусок, который только что был выделен уже).
← →
test_test (2011-04-07 09:07) [17]
> А реально ли повторить подобную конструкцию, но кашерно.
Тю чо это я.
создать новую структуру
с полями MaxSize, Size integer и полем data pchar;
затем передаваемый в функцию указатель приводить к этой структуре и полю date делать new char [size*sizeof(нужный тип)]
← →
Inovet © (2011-04-07 21:55) [18]> [15] test_test (07.04.11 07:11)
> А реально ли повторить подобную конструкцию, но кашерно.
Класс сделай что ли с виртуальными методами...
← →
test_test (2011-04-08 18:05) [19]О!
> test_test (07.04.11 09:07) [17]
Это работает как нужно.
> Класс сделай что ли с виртуальными методами...
Да не умею я их делать пока на сятине, на делфях умею, а на сятине нет.
Может ктонить найдется такой щедрый и покажет как, только с объяснялками...
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2011.07.24;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.003 c