2014-03-30 2 views
2

Я пытаюсь сделать функцию для вызова другой функции, которая расположена по определенному адресу. Функция, вызывающая другие функции, принимает только типы аргументов, переданных в (как char *), тип возврата и сами аргументы. Но он внезапно падает каждый раз при вызове самой функции или после ее вызова. В общем, что я пытаюсь достичь, есть функция записи, как это в C++:Функция вызова по адресу с ранее переданными аргументами

function callfunc(name,...) --Lua 
local func=_G[name]; 
func(...) 
end 

Так вот мой код:

#include <stdio.h> 
#include <stdarg.h> 
void testfunc(char *c){ 
    printf("Text: %s\n",c); 
} 
void callfunc(void *ptr,char ret,char *types,int argc,...){ 
//#define push(w,h,t) *(t*)(w-sizeof(t))=h; w-=sizeof(t) 
#define push(w) asm("push %0"::"r"(w)) 
    typedef void (*funcptr)(...); 
    typedef char* char_ptr; 
    funcptr func=(funcptr)ptr; 
    double d; 
    char *p; 
    int n; 
    va_list vl; 
    va_start(vl, argc); 
    for(int i=0;i<argc;i++){ 
     switch(types[i]){ 
      case 'p': 
       p=va_arg(vl,char_ptr); 
       printf("Pushing char*: %s\n",p); 
       push(p); 
       break; 
      case 'n': 
       n=va_arg(vl,int); 
       printf("Pushing int: %d",n); 
       push(n); 
       break; 
      case 'd': 
       d=va_arg(vl,double); 
       printf("Pushing double: %f",d); 
       push(d); 
       break; 
     } 
    } 
    va_end(vl); 
    asm(
     "call *%0" 
     ::"r"(func) 
    ); 
} 
int main(int argc, const char * argv[]) 
{ 
    //address can be directly set to lets say 0x450F10E0 
    //we only know what is passed to function, we cant change function itself 

    callfunc((void*)testfunc,'v',"p",1,"Hi!"); 
    return 0; 
} 

Может кто-нибудь помочь?

Редактировать Функция, которую я хочу назвать, __stdcall.

+0

См. Также http://stackoverflow.com/questions/16142284/convert-inline-assembly-code-to-c и http://stackoverflow.com/questions/16294841/inline-assembly-language –

ответ

1

Не общайтесь с va_list, это очень не переносное. В частности, на многих платформах ABI есть аргумент, передающий некоторые параметры в регистрах, вы полностью упускаете этот аспект. (Вы даже не указали нам, какой ABI вы используете.)

Эти способы, которые предусмотрены стандартом, должны передать va_list функции, которую вы хотите вызвать, и выполнять интерпретацию аргументов.

Смежные вопросы