Değişken işlevlere dinamik olarak parametreleri itmek için ffcall (özellikle fccall'ın avcall paketi) kütüphanesini kullanıyorum. yanivoid işaretçiler ve ffcall kitaplığı
ve bu işlevi kullanıcıdan alınan değerlerle çağırmak istiyoruz. Bunu yapmak için, biz fonksiyonun bir avcall sürümünü oluşturmak:
int read_row (struct some_struct *a, struct another_struct *b[], ...);
Ve şöyle kullanılır:: Artık
int av_blah (char *a, int b, double c, char **values, int num_of_values)
{
av_alist alist;
int i, ret;
av_start_int (alist, &blah, &ret); //let it know which function
av_ptr (alist, char*, a); // push values onto stack starting from left
av_int (alist, b);
av_double (alist, c);
for (i=0;i<num_of_values;i++)
{
// do what you want with values and add to stack
}
av_call (alist); //call blah()
return (ret);
}
, beraber avcall kullanıyorum fonksiyonudur
struct some_struct a;
struct another_struct **b = fill_with_stuff();
char name[64];
int num;
while (read_row (&a, b, name, &num)==0)
{
printf ("name=%s, num=%d\n", name, num);
}
Ancak bu işlevden belirli bir miktar değer yakalamak için avcall kullanmak istiyorum ve bu bilgiyi önceden bilmiyorum. Yani ben sadece türüne göre bir boşluk işaretçiler dizisi ve ardından malloc alan oluşturmak düşündüm:
char printf_string[64]=""; //need to build printf string inside av_read_row()
void **vals = Calloc (n+1, sizeof (void*)); //wrapper
while (av_read_row (&a, b, vals, n, printf_string) == 0)
{
// vals should now hold the values i want
av_printf (printf_string, vals, n); //get nonsense output from this
// free the mallocs which each vals[i] is pointing to
void **ptrs = vals;
while (*ptrs) {
free (*ptrs); //seg faults on first free() ?
*ptrs=NULL;
ptrs++;
}
//reset printf_string
printf_string[0]='\0';
printf ("\n");
}
Ve av_read_row
adildir:
int av_read_row (struct some_struct *a, struct another_struct *b[], void **vals, int num_of_args, char *printf_string)
{
int i, ret;
av_alist alist;
av_start_int (alist, &read_row, &ret);
av_ptr (alist, struct some_struct *, a);
av_ptr (alist, struct another_struct **, b);
for (i=0;i<num_of_args;i++)
{
switch (type) //for simplicity
{
case INT: {
vals[i] = Malloc (sizeof (int));
av_ptr (alist, int*, vals[i]);
strcat (printf_string, "%d, ");
break;
}
case FLOAT: {
//Same thing
}
//etc
}
}
av_call (alist);
return (ret);
}
Ben bellek bozulması nedeniyle bir demet yaşanmaktadır hatalar ve burada yaptığım şeyden hoşlanmıyormuş gibi görünüyor. Bunu yaptığım gibi yanlış bir şey tespit edemem, değil mi? Şu anda, döngü sırasında av_read_row
içerisindeki malloları boşaltmaya çalıştığımda hoşlanmıyor. Bir şeyleri yanlış yaptığımı gören var mı? Yığın sınırlıdır olarak
Teşekkür
Sanırım senin strcat'in bir şey eksik ... Av_ şeyler hakkında çok aşina değilim, ama eğer printf_string üzerine yazıyorsa, bazı kötü sonuçlar alacaksınız. –
Kullanmakta olduğunuz paket bu mu (http://www.haible.de/bruno/packages-ffcall.html)? –