Partilhar via


__clrcall

Específicos do Microsoft

Especifica uma função só pode ser chamada de código gerenciado.Use __clrcall para todas as funções virtuais que só serão chamadas de código gerenciado.No entanto, esta convenção de chamada não pode ser usada para funções que serão chamadas de código nativo.

Use __clrcall para melhorar o desempenho ao chamar uma função gerenciada para uma função virtual gerenciada ou função gerenciada a função gerenciada através de ponteiro.

Pontos de entrada são funções separadas, gerado pelo compilador.Se uma função tem dois pontos de entrada nativo e gerenciado, uma delas será a função real com a implementação da função.Outra função será uma função separada (uma conversão) que chama a função real e permite que o common language runtime execute PInvoke.Ao marcar uma função como __clrcall, indicam a implementação da função deve ser a MSIL e que a função de ponto de entrada nativo não será gerada.

Ao colocar o endereço de uma função nativa se __clrcall não for especificado, o compilador usa o ponto de entrada nativo.__clrcallindica que a função é gerenciada e não há necessidade de percorrer a transição de gerenciado para nativo.Nesse caso, o compilador usa o ponto de entrada gerenciado.

Quando /clr (não /clr:pure ou /clr:safe) é usado e __clrcall não é usado, pegar o endereço de uma função sempre retorna o endereço da função de ponto de entrada nativo.Quando __clrcall é usado, a função de ponto de entrada nativo não é criada para obter o endereço da função gerenciada, não uma função de conversão de ponto de entrada.Para mais informações, consulte Duplo conversão (C++).

/CLR (common Language Runtime Compilation)significa que todas as funções e ponteiros de função são __clrcall e o compilador não permitirá uma função de compiland seja marcado como algo diferente de __clrcall.Quando /clr:pure é usado, __clrcall só pode ser especificado em ponteiros de função e declarações externas.

Você pode chamar diretamente __clrcall funções de código C++ existente que foi compilado usando /clr como essa função tem uma implementação de MSIL.__clrcallfunções não podem ser chamadas diretamente de funções embutidas asm e chamar intrinisics específico da CPU, por exemplo, mesmo que essas funções são compiladas com /clr.

__clrcallponteiros de função só devem ser usados no domínio do aplicativo em que foram criados.Em vez de passar __clrcall ponteiros de função em domínios de aplicativo, use CrossAppDomainDelegate.Para mais informações, consulte Domínios de aplicativos e Visual C++.

Exemplo

// clrcall.cpp
// compile with: /clr:oldSyntax /LD
void __clrcall Test1( ) {}
void (__clrcall *fpTest1)( ) = &Test1;

Observe que quando uma função é declarada com __clrcall, o código será gerado quando necessário; Por exemplo, quando função é chamada.

// 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();
}
  

O exemplo a seguir mostra que você pode definir um ponteiro de função, de modo que declare que o ponteiro de função será chamado somente de código gerenciado.Isso permite que o compilador chamar a função gerenciada diretamente e evitar o ponto de entrada nativo (problema de conversão dupla).

// clrcall3.cpp
// compile with: /clr
void Test() {
   System::Console::WriteLine("in Test");
}

int main() {
   void (*pTest)() = &Test;
   (*pTest)();

   void (__clrcall *pTest2)() = &Test;
   (*pTest2)();
}

Consulte também

Referência

Argumento passando e convenções de nomenclatura

Palavras-chave C++