STDCALL mutilazione dei nomi utilizzando C e dllexport extern vs definizioni dei moduli (MSVC ++)
-
13-10-2019 - |
Domanda
I stava cercando di esportare una funzione di test semplice per un dll di lavorare con un'applicazione (FYI: mIRC) che specifica la convenzione di chiamata come:
int __stdcall test_func(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause)
Ora, per chiamare questo dall'applicazione, sarei usando test_func , ma ho notato a causa di mutilazione dei nomi non è così semplice come avevo pensato.
Con argomenti simili qui sono venuto a comprendere che l'utilizzo di extern metodo di rimozione storpiatura "C" in combinazione con __ declspec (dllexport) è un equivelant (un po ') alle definizioni modulo (DEF). Tuttavia, quando si utilizza il extern / dllexport metodo mia funzione (come esempio) è sempre _test_func @ numeri , mentre il DEF rimosso tutti storpiatura come richiesto per l'utilizzo con l'applicazione avevo bisogno di esportazione.
Qualcuno potrebbe spiegare perché questo è? Sono solo curioso di sapere i due metodi. Grazie!
Soluzione
dllexport / importazione sono stati progettati per essere di nuovo caricata da soli, non una vecchia libreria C utilizzando GetProcAddress. La storpiatura avete visto è quello che tutti i compilatori Microsoft hanno fatto per un tempo lungo per __stdcall funzioni. Molto probabilmente, il vostro obiettivo sia aspetta una funzione __cdecl, non __stdcall, ma in caso contrario, sarà necessario utilizzare un file .def per specificamente non-mangano il nome.
Altri suggerimenti
extern "C"
non ha nulla a che fare con stdcall: si dichiara soltanto che C ++ nome storpiatura (aka tipo di sicurezza linkage, l'inclusione di informazioni di tipo in nome del simbolo) è disabilitata. È necessario usarlo indipendentemente dal fatto che si utilizza C convenzione di chiamata o convenzione di chiamata stdcall.
In stdcall convenzione di chiamata, il chiamato rimuove i parametri dallo stack. Per fare che sicuro, il nome esportato contiene il numero di byte che il chiamato rimuoverà dallo stack.
Se l'applicazione che si sta esportando a richiede che nessun suffisso @number
viene aggiunto al nome, probabilmente significa che si prevede C convenzione di chiamata. Quindi, si dovrebbe smettere di dichiarare la funzione di __stdcall
. Quando la dichiareremo come declspec(dllexport)
, si dovrebbe ottenere un nome non decorato nella DLL.
Nel file DEF, è possibile chiamare la funzione quello che vuoi; nessuna verifica supplementare viene eseguita.