Пользовательская функция Malloc() :: Что означает этот синтаксис?

Я пишу программу на C с библиотекой nDPI, доступной здесь. (Кодирование на машине Ubuntu, компилятор GCC, nDPI версии 3.2) nDPI используется для проверки сетевого трафика. Код использует множество различных структур для представления сетевых вещей, таких как сетевые потоки, сетевые протоколы, сетевые узлы и т. Д.

Поэтому я думаю, что если вы хотите создать эти структуры, вы должны использовать пользовательский malloc() и free()функции, что имеет смысл. Но мне сложно понять прототипы функций. Вот несколько соответствующих строк кода из файла заголовка API:

/* Utility functions to set ndpi malloc/free/print wrappers */

void set_ndpi_flow_malloc(void* (*__ndpi_flow_malloc)(size_t size));

void set_ndpi_flow_free(void (*__ndpi_flow_free)(void *ptr));

Рассмотрим set_ndpi_flow_malloc()функция. В другом месте исходного кода есть struct nDPI_flow_infoопределен, и я вижу, что эта структура используется повсюду в коде. Так что я предполагаю set_ndpi_flow_malloc() состоит в том, чтобы разместить одну из этих структур в куче, возможно, заполнить ее некоторой информацией и вернуть указатель.

Но я не понимаю аргументов этой функции. Если бы мне пришлось угадывать, я бы сказал, что set_ndpi_flow_malloc() принимает указатель на другую функцию, называемую __ndpi_flow_malloc(), и эта функция принимает size_tцелое число в качестве аргумента. Оказывается, прототип функции есть где-то в другом месте заголовочного файла API:

void * ndpi_flow_malloc(size_t size);

Вот такая функция мне нужна: мне нужно __ndpi_flow_malloc() (два подчеркивания перед именем) Что означают эти двойные подчеркивания?

Другой вопрос... если set_ndpi_flow_malloc() это обычай malloc() функция, не должна ли она возвращать указатель на выделенную память?

Другой вопрос... Как бы я на самом деле написал это в своем коде? Как это...?

struct nDPI_flow_info* myFlow;

set_ndpi_flow_malloc( (void*) &ndpi_flow_malloc( sizeof( struct nDPI_flow_info )) );

// ...use the struct...

set_ndpi_flow_free( &ndpi_flow_free* myFlow ) );

Это не может быть правдой. Я не понимаю, как вторая строка возвращает указатель и присваивает его переменной myFlow.

Любые советы или критика приветствуются. Благодаря!

ПОЛНОЕ РАСКРЫТИЕ: Я также разместил этот вопрос здесь.

2 ответа

Решение

Функция set_ndpi_flow_mallocна самом деле не выполняет распределение, но позволяет вам установить функцию, которая выполняет. Его аргумент - указатель на функцию, которая принимает size_t и возвращает void *, а имя аргумента - __ndpi_flow_malloc.

То же самое касается set_ndpi_flow_free. Он сообщает библиотеке, какую функцию использовать в качестве настраиваемой бесплатной функции.

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

set_ndpi_flow_malloc(ndpi_flow_malloc);

Затем, предполагая, что существует аналогичная бесплатная функция по умолчанию, называемая ndpi_flow_free, вы должны сделать это, чтобы установить его как пользовательскую бесплатную функцию:

set_ndpi_flow_free(ndpi_flow_free);

Я не знаком с этим API, но исходя из того, что вы разместили здесь, он должен выделять внутреннюю память для выполнения некоторых операций, и он позволяет вам указать, какой распределитель / освободитель он должен использовать для этого - он может либо использовать vanilla malloc и free для выделения и освобождения памяти, или вы можете передать настраиваемый распределитель / освободитель, который использует другую схему распределения или оснащен инструментами для ведения журнала / отладки или чего-то еще.

Чтобы облегчить чтение, я собираюсь переименовать вещи. В основном притворись, что я сделал

#define SNFM set_ndpi_flow_malloc
#define NFM  __ndpi_flow_malloc

Это оставляет нас с

void SNFM(void *(*NFM)(size_t size));

который читается как

     SNFM                               -- SNFM
     SNFM(                         )    -- is a function taking
     SNFM(        NFM              )    --   parameter NFM
     SNFM(      (*NFM)             )    --   is a pointer to
     SNFM(      (*NFM)(           ))    --     a function taking
     SNFM(      (*NFM)(       size))    --       parameter size
     SNFM(      (*NFM)(size_t size))    --       is a size_t
     SNFM(     *(*NFM)(size_t size))    --     returning a pointer to
     SNFM(void *(*NFM)(size_t size))    --       void
void SNFM(void *(*NFM)(size_t size));   -- returning void

Итак, аргумент в пользу set_ndpi_flow_malloc указатель на функцию, которая принимает size_t и возвращает указатель на void - т.е. malloc или функция с такой же подписью, которая делает то же самое:

set_ndpi_flow_malloc( malloc );

или же

void *my_malloc( size_t size )
{
  ...
}
...
set_ndpi_flow_malloc( my_malloc );

Эта функция не выделяет память; вместо этого вы указываете, какой распределитель использовать, когда библиотеке необходимо выделить внутреннюю память. set_ndpi_flow_free делает то же самое с деаллокатором - вы можете использовать ванильный free из стандартной библиотеки или передайте настраиваемый освободитель:

set_ndpi_flow_free( free );

или же

void my_free( void *ptr )
{
  ...
}
...
set_ndpi_flow_free( my_free );
Другие вопросы по тегам