__clrcall
Específicos de Microsoft
Especifica que una función sólo se puede llamar desde código administrado.Uso __clrcall para todas las funciones virtuales que sólo se llamará desde código administrado.Sin embargo esta convención de llamada no se puede utilizar para las funciones que se pueden llamar desde código nativo.
Uso __clrcall para mejorar el rendimiento cuando se llama desde una función administrada a una función administrada virtual o desde una función administrada a una función administrada a través del puntero.
Puntos de entrada son funciones independientes, generado por el compilador.Si una función tiene dos puntos de entrada nativo y administrado, uno de ellos será la función real con la implementación de la función.La otra función será una función independiente (un código thunk) que llama a la función real y permite a common language runtime realizar PInvoke.Cuando se marca una función como __clrcall, indicar la implementación de la función debe ser MSIL y que no se generará la función de punto de entrada nativo.
Al tomar la dirección de una función nativa si __clrcall no se especifica, el compilador utiliza el punto de entrada nativo.__clrcallindica que la función se administra y hay necesidad de ir a través de la transición de no administrado a nativo.En ese caso el compilador utiliza el punto de entrada administrado.
Cuando /clr (no /clr:pure o /clr:safe) se utiliza y __clrcall no es se utiliza, tomar la dirección de una función siempre devuelve la dirección de la función de punto de entrada nativo.Cuando __clrcall es utilizado, la función de punto de entrada nativo no se crea, por lo que obtener la dirección de la función administrada, no una función de código thunk de punto de entrada.Para obtener más información, vea Doble thunk (C++).
/clr (Compilación de Common Language Runtime)implica que todas las funciones y punteros de función son __clrcall y el compilador no permitirá que una función dentro de la operación de compilación se marque todo lo que __clrcall.Cuando /clr:pure se utiliza, __clrcall sólo puede especificarse en declaraciones externas y punteros a función.
Se puede llamar directamente a __clrcall funciones de código C++ existente que se compiló mediante el uso de /clr siempre y cuando dicha función tiene una implementación de MSIL.__clrcallfunciones no se puede llamar directamente desde funciones inline asm y llamar a intrinisics de la específica de la CPU, por ejemplo, incluso si esas funciones se compilan con /clr.
__clrcallpunteros a función sólo están diseñados para utilizarse en el dominio de aplicación en el que se crearon.En lugar de pasar __clrcall punteros de funciones a través de dominios de aplicación, utilice CrossAppDomainDelegate.Para obtener más información, vea Dominios de aplicación y Visual C++.
Ejemplo
// clrcall.cpp
// compile with: /clr:oldSyntax /LD
void __clrcall Test1( ) {}
void (__clrcall *fpTest1)( ) = &Test1;
Tenga en cuenta que cuando se declara una función con __clrcall, se generará el código cuando sea necesario; Por ejemplo, cuando se llama a función.
// clrcall2.cpp
// compile with: /clr
using namespace System;
int __clrcall Func1() {
Console::WriteLine("in Func1");
return 0;
}
// Func1 hasn't been used at this point (code has not been generated),
// so runtime returns the adddress of a stub to the function
int (__clrcall *pf)() = &Func1;
// code calls the function, code generated at difference address
int i = pf(); // comment this line and comparison will pass
int main() {
if (&Func1 == pf)
Console::WriteLine("&Func1 == pf, comparison succeeds");
else
Console::WriteLine("&Func1 != pf, comparison fails");
// even though comparison fails, stub and function call are correct
pf();
Func1();
}
El siguiente ejemplo muestra que puede definir un puntero a función, tal que declare que el puntero de función sólo se invocará desde código administrado.Esto permite al compilador llamar directamente a la función administrada y evitar el punto de entrada nativo (problema de double thunk).
// clrcall3.cpp
// compile with: /clr
void Test() {
System::Console::WriteLine("in Test");
}
int main() {
void (*pTest)() = &Test;
(*pTest)();
void (__clrcall *pTest2)() = &Test;
(*pTest2)();
}