scritura de funciones desnudas con prólogo personalizado y código de epílogo en Visual Studio

Estoy escribiendo un código de complemento en un dll que es llamado por un host sobre el que no tengo control.

El host supone que los complementos se exportan como funciones __stdcall. Al host se le dice el nombre de la función y los detalles de los argumentos que espera y desvía dinámicamente una llamada a través de LoadLibrary, GetProcAddress y empuja manualmente los argumentos a la pila.

Usualmente los plugins dlls exponen una interfaz constante. Mi complemento expone una interfaz que está configurada en el tiempo de carga dll. Para lograr esto, mi complemento expone un conjunto de puntos de entrada estándar que se definen en el momento en que se compila el dll y los asigna según sea necesario a la funcionalidad interna que está siendo expuesta.

Cada una de las funciones internas puede tomar diferentes argumentos, pero esto se comunica al host junto con el nombre del punto de entrada físico. Todos mis puntos de entrada dll físicos están definidos para tomar un solo puntero void * y marco los parámetros posteriores de la pila yo mismo trabajando desde los desplazamientos desde el primer argumento y la lista de argumentos conocidos que se ha comunicado al host.

El host puede llamar con éxito a las funciones de mi complemento con los argumentos correctos y todo funciona bien ... Sin embargo, soy consciente de que a) mis funciones no están limpiando la pila como se supone que deben hacerlo se definen como funciones __stdcall que toman un puntero de 4 bytes y, por lo tanto, siempre hacen un 'ret 4' al final, incluso si la persona que llama ha introducido más argumentos en la pila. y b) No puedo manejar funciones que no toman argumentos, ya que ret 4 mostrará 4 bytes de la pila a mi regreso.

Al rastrear mi plugin en el código de llamada del host, puedo ver que en realidad a) no es tan importante; el anfitrión pierde algo de espacio en la pila hasta que regresa de la llamada de despacho, en cuyo punto limpia su marco de pila que limpia mi basura; sin embargo..

Puedo resolver b) cambiando a __cdecl y no limpiando nada. Supongo que puedo resolver a) cambiando a funciones desnudas y escribiendo mi propio código genérico de limpieza de argumentos.

Ya que sé la cantidad de espacio de argumento utilizado por la función que se acaba de llamar, esperaba que fuera tan simple como:

extern "C" __declspec(naked) __declspec(dllexport) void  * __stdcall EntryPoint(void *pArg1)
{                                                                                                        
   size_t argumentSpaceUsed;
   {
      void *pX = RealEntryPoint(
         reinterpret_cast<ULONG_PTR>(&pArg1), 
         argumentSpaceUsed);

      __asm
      {
         mov eax, dword ptr pX
      }
   }
   __asm
   {
      ret argumentSpaceUsed
   }
}

Pero eso no funciona ya que ret necesita una constante de tiempo de compilación ... ¿Alguna sugerencia?

ACTUALIZADO

Gracias a las sugerencias de Rob Kennedy, he llegado a esto, lo que parece funcionar ...

extern "C" __declspec(naked) __declspec(dllexport) void  * __stdcall EntryPoint(void *pArg1)
{      
   __asm {                                                                                                        
      push ebp          // Set up our stack frame            
      mov ebp, esp  
      mov eax, 0x0      // Space for called func to return arg space used, init to 0            
      push eax          // Set up stack for call to real Entry point
      push esp
      lea eax, pArg1                
      push eax                      
      call RealEntryPoint   // result is left in eax, we leave it there for our caller....         
      pop ecx 
      mov esp,ebp       // remove our stack frame
      pop ebp  
      pop edx           // return address off
      add esp, ecx      // remove 'x' bytes of caller args
      push edx          // return address back on                   
      ret                        
   }
}

¿Se ve bien?

Respuestas a la pregunta(2)

Su respuesta a la pregunta