2011-09-24 19 views
5

Ho una funzione in una DLL:Chiamare un UnmanagedFunctionPointer in C# per convenzioni di chiamata personalizzati

char __usercall MyUserCallFunction<al>(int arg1<esi>) 

perché io odio me stesso mi piacerebbe chiamare questo dall'interno di C# utilizzando P/Invoke.

Normalmente questo può essere fatto da ottenere una funzione di delegato, a la:

[UnmanagedFunctionPointer(CallingConvention.ThisCall, CharSet = CharSet.Auto, SetLastError = true)] 
    public delegate char DMyUserCallFunction(IntPtr a1); 

E poi invoca, facendo:

var MyFunctionPointer = (DMyUserCallFunction)Marshal.GetDelegateForFunctionPointer(AddressOfFunction, typeof(DMyUserCallFunction)); 

MyFunctionPointer(IntPtr.Zero); 

Per utente personalizzata convenzioni di chiamata, tuttavia, questo farà sì che il programma in crash. C'è un modo in cui posso farlo usando codice non sicuro o una sorta di funzione wrapper che mette in posizione i delegati, ma non mi costringe a scrivere una DLL C++?

Grazie!

Edit:

Come suggerito da DTB, ho creato un piccolo DLL C++ che io uso tramite P/Invoke per chiamare la funzione. Per chiunque sia curioso la funzione in C++ finisce per assomigliare:

extern "C" __declspec(dllexport) int __stdcall callUsercallFunction(int functionPointer, int arg1) 
{ 
    int retVal; 

    _asm 
    { 
     mov esi, arg1 
     call functionPointer 
     mov retVal, eax 
    } 

    //Fake returning al, the lower byte of eax 
    return retVal & 0x000000FF; 
} 
+5

+1 per "Perché odio me stesso" – dtb

+0

Perché hai bisogno del delegato? Non puoi fare '[DllImport (...)] byte esterno MyUserCallFunction (IntPtr a1)'? – dtb

+0

La funzione non viene effettivamente esportata. Devo chiamare la funzione iniettando in un processo che carica la DLL. Sto usando EasyHook per questo - l'obiettivo è quello di agganciare qualsiasi funzione arbitraria che posso trovare usando IDA all'interno della DLL. – mweber

risposta

2

Non c'è speranza di attuare personalizzati convenzioni di chiamata in C#. È necessario eseguire ciò in una DLL nativa o una DLL C++/CLI.