2016-06-29 4 views
-1

Ich habe ein Makro wie folgt definiert:Wie behebe ich diese Warnung zum Übergeben eines Funktionszeigers an einen Makro in C?

#define _call(func_name, __func_proto, ...)  {  \ 
void *_handle;           \ 
int result = !CERR_V_SUCCESS;        \ 
                   \ 
    _handle = dlopen(_DLL_NAME,GLOBAL); \ 
    if (_handle) {           \ 
     __func_proto = dlsym(dll_handle, func_name);   \ 
     if (__func_proto) {          \ 
      result = (*__func_proto)(__VA_ARGS__);    \ 
    }              \ 
     (void)dlclose(_handle);        \ 
    }               \ 
    return (result);           \ 
} 

ich so dieses Makro mit verschiedenen Funktionszeiger nenne:

_call("download",_download,src,dst); 
_call("upload",_upload,src,dst); 
_call("test",_test,file); 

und die Funktionszeiger als

int (*_download)(int *,int *); 
int (*_upload)(int *,int*); 
int (*_test)(int *,char*); 

definiert Diese führt zu einer Warnung a value of type "void *" cannot be assigned to an entity of type "int (*)(int*,int*)".

Wie kann ich diese Warnung beheben?

+2

Ist das Ihr eigentliches Makro? – molbdnilo

+0

Ja, ich habe dieses Makro definiert, um einige DLLs zu laden, ich habe hier keine Definition hinzugefügt, aber es hat auch Definitionen – mjht

+0

Sieht aus wie Cast fehlt, aber ohne das eigentliche Makro ist es schwer zu sagen – buld0zzr

Antwort

1

Sie müssen Umwandlungen hinzufügen, da void * nicht automatisch zu/von Funktionszeigern konvertiert wird. In der Tat ist es nicht portabel anzunehmen, dass Funktionszeiger überhaupt als void * ausgedrückt werden können.

Natürlich, wenn Sie auf einem System sind, das dlopen() und Freunde hat, kann es eine sichere Annahme sein, dass diese Plattform diese Konvertierung unterstützt.

Auch das klingt sehr seltsam das ganze dlopen()/dlsym()/dlclose() Tanz pro Anruf zu tun, in der Regel, um die Zeiger puffern.

3

Documentation of dlsym schlägt vor, sollten Sie die Funktionszeiger auf void* werfen, bevor Sie den Rückgabewert auf den Zeiger zuweisen:

*(void **)(&__func_proto) = dlsym(dll_handle, func_name); 

Rationale hinter dem Link beschrieben:

Die Norm ISO C nicht erfordern, dass Zeiger auf Funktionen zu Zeigern auf Daten hin und her geworfen werden können. Tatsächlich verlangt der ISO-C-Standard nicht, dass ein Objekt vom Typ void * einen Zeiger auf eine Funktion halten kann. Implementierungen, die die XSI-Erweiterung unterstützen, erfordern jedoch, dass ein Objekt vom Typ void * einen Zeiger auf eine Funktion enthalten kann.

Note, die der ISO C Standard-Compiler konform sind erforderlich, um eine Warnung zu erzeugen, wenn eine Umwandlung von einem void * Zeiger auf einen Funktionszeiger wie in versucht wird:

fptr = (int (*) (int)) dlsym (handle, "my_function");

+0

Nitpicking: Das Snippet, das du zeigst, wird * nicht * in 'void *' umgewandelt. – alk

Verwandte Themen