Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
1-1261019733
Phantomouse
2009-12-17 06:15
2011.07.24
Самопроизвольное появление формы


1-1260380174
alexan
2009-12-09 20:36
2011.07.24
Циклы


8-1214048535
Al
2008-06-21 15:42
2011.07.24
Как сделать в функции динамическую переменную?


2-1303294957
jacksotnik
2011-04-20 14:22
2011.07.24
помогите с задачкой


1-1260966363
Andrews
2009-12-16 15:26
2011.07.24
Компонент для окна с настройками программы





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский