LINUX.ORG.RU

g_thread_create и va_list


0

0

Есть функция abc(a,b,...). В ее теле я должен создать поток и передать набор параметров va_args... что то вида:

void
abc(a, b, ...)
{
  GError *err;
  va_list args;
  <skipped>
  va_start(args, b);
  // вот здесь надо как-то подшаманить с args и засунуть в f
  g_thread_create(threaded_func, (gpointer) f, TRUE, &err);
  va_end (args);
  <skipped>
}

кто-нибудь что-то подобное делал? ну или просто знает как это делать?

PS: threaded_func является GThreadFunc, т.е. тип ее должен быть такой:

gpointer  (*GThreadFunc)  (gpointer data);

Deleted

va_list есть ничто иное, как учазатель на параметры в стэке, поэтому они уничтожаются по окончанию вызова функции. Следовательно, перед вызвом g_thread_create нужно скопировать все параметры во что-нибудь и передавать указатель на копию.

Копия создается путем последовательного перебора параметров присвоением типа f[i] = va_arg(args, some_type). some_type может быть любым, но в реальности для платформ, на которых работает GLib, это всего-лишь gint, glong, gint64, gdouble и gpointer.

Надеюсь, что кол-во и тип параметров проблемой не является, иначе RTFM.

ShprotX
()

делаешь какой-нибудь список (GList ЕМНИП) и копируешь туда

кол-во элементов просто так выяснить нельзя. поставь, например, спереди их кол-во.

generatorglukoff ★★
()
Ответ на: комментарий от generatorglukoff

> делаешь какой-нибудь список (GList ЕМНИП) и копируешь туда

Ну-у-у, зачем же так ограничивать одним глистом, может ему больше GHash подойдет? Или простой кусок памяти via g_new()/g_malloc().

ShprotX
()
Ответ на: комментарий от ShprotX

Хорошо, этот список я создал, передал в потоковую функцию... я наверное не совсем точно объяснил - тут как раз проблема в том, что в теле потоковой функции я должен дальше вызвать другую функцию, которая в парамах имеет va_list. Т.е.

void abc (a,b,...) { threaded_func(...) }

GThread threaded_func(gpointer p) { def(d,e,...) }

в вызове def я должен передать набор параметров, которые пришли в abc. собственно мне не интересно каким путем доставить значения параметров в threaded_func, мне интересно протолкнуть их дальше в def, при этом функция по параметрам должна быть идетнтична abc... правильнее сказать, тип функций abc и def должен быть одинаковый. Т.о. мне нужно как-то сохранить значения стека (это и не проблема), далее в функции threaded_func сформировать стек по образу и подобию при вызове abc.

Deleted
()
Ответ на: комментарий от Deleted

вот приведу такой пример... я пишу аналог printf, но мне надо дать
 функционал выполнения ее в бекграунде... чтобы не лепить кучу 
функций, я делаю "прокладку", которая механизмом рекурсии переводит в 
бекграунд

GThread my_printf_do_bg (gpointer gp)
{

   my_printf(FALSE, <вот здесь нужны те самые "..." параметры)  

}

void my_printf(gboolean in_bg, gchar *tmpl, ...)
{
  GError *err;
  va_list args;
  gpointer gp; // считаем что это указатель на инициализированную структуру

  

  if (in_bg)
  {
    va_start(args,tmpl);
  //здесь к примеру мы засовываем все параметры в структуру gp
    va_end (args);
    g_thread_create (my_printf_do_bg,
                     gpointer gp,
                     TRUE,
                     &err);
    return;
  }

  // раз пришли сюда, значит мы уже в потоке и занимаемся 
 // непосредственно реализацией нужного функционала... вывода на экран

};
 

где-то в коде я делаю вызов  следующим образом:

my_printf(TRUE, "%s %d %s", "aaaa", 1111, "bbbb");


Т.е. картина получается следующая... при вызове "my_printf(TRUE," мы 
попадем в блок "if (in_bg)". Далее она вызовет "my_printf_do_bg", 
которая в свою очередь вызовет "my_printf(FALSE,". Так вот, нужно 
чтобы va_list у вызова "my_printf(TRUE," попал в вызов 
"my_printf(FALSE,"

Deleted
()
Ответ на: комментарий от Deleted

есть подозрение что можно воспользоваться av_call(alist); Но что-то я до конца не вкурил сути... чисто интуитивно. Если так, то на сколько это будет "транспортабельно" между платформами?

Deleted
()
Ответ на: комментарий от ShprotX

>Идеальный вариант - избавиться от va_list везде, где это возможно.

у меня потребность в переменном кол-ве параметров слишком похожа на printf. Сможешь сделать printf с жестким кол-вом параметров? :)

Deleted
()
Ответ на: комментарий от Deleted

ага, буду передавать список параметров :) тоесть будет один единственный параметр... ну это так... lisp, знаешь, он решает %)

Cy6erBr4in ★★★
()
Ответ на: комментарий от Cy6erBr4in

>кстати, а чё там с GList? он умеет хранить разнородные элементы?

так с ним то и нет проблем, GList, просто список указателей. я ж говорю, мне надо умудриться передать переменный список параметров через "узкое горлышко" в виде одного параметра gpointer при создании потока... точнее даже не передать (упакую хоть в структуру, хоть в список.. не важно), а воссоздать этот список параметров для возможности вызова функции, у которой вид def(d,e,...). нужно именно "..." воссоздать.

Deleted
()
Ответ на: комментарий от generatorglukoff

мне кажется ты не внимательно прочитал мой пост с примером my_printf, где я объяснял суть необходимого. ладно, вобщем буду копать сам, покуда я так и не вижу, что кто-то с подобным сталкивался. как найду решение, отпишу здесь.

Deleted
()
Ответ на: комментарий от Deleted

Почти всегда, когда пишется функция с переменным количеством параметров полезно писать парную принимающую va_list. Вот и в этом случае нужно скопировать va_list. в "abc" и вызывать не "def", а "defv" (или как ее там?)

k_andy ★★★
()
Ответ на: комментарий от k_andy

я на примере my_printf показал,что у меня рекурсивный вызов. можно конечно огород функций для простоты жизни наваять, но хочется красоты и изящества.

Deleted
()
Ответ на: комментарий от Deleted

Вот тот самый пример нужно писать как функцию принимающую va_list., а фукцию с переменным число параметров реализовать как ее wrapper.

k_andy ★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.