Edição: Eu escrevi os resultados como um post no blog .
O compilador C # trata os tipos COM de maneira um pouco mágica. Por exemplo, esta declaração parece normal ...
Word.Application app = new Word.Application();
... até você perceber que Application
é uma interface. Chamando um construtor em uma interface? Yoiks! Na verdade, isso é traduzido em uma chamada para Type.GetTypeFromCLSID()
e outra para Activator.CreateInstance
.
Além disso, no C # 4, você pode usar argumentos não-ref para ref
parâmetros, e o compilador apenas adiciona uma variável local para passar por referência, descartando os resultados:
// FileName parameter is *really* a ref parameter
app.ActiveDocument.SaveAs(FileName: "test.doc");
(Sim, faltam vários argumentos. Os parâmetros opcionais não são bons? :)
Estou tentando investigar o comportamento do compilador e não estou conseguindo falsificar a primeira parte. Eu posso fazer a segunda parte sem nenhum problema:
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
[ComImport, GuidAttribute("00012345-0000-0000-0000-000000000011")]
public interface Dummy
{
void Foo(ref int x);
}
class Test
{
static void Main()
{
Dummy dummy = null;
dummy.Foo(10);
}
}
Eu gostaria de poder escrever:
Dummy dummy = new Dummy();
Apesar. Obviamente, vai estragar no momento da execução, mas tudo bem. Estou apenas experimentando.
Os outros atributos adicionados pelo compilador para PIAs COM vinculados ( CompilerGenerated
e TypeIdentifier
) não parecem fazer o truque ... qual é o molho mágico?
fonte
dynamic
... estamos acostumados a digitar estático / forte para ver por que isso importa fora do COM.Respostas:
De maneira alguma sou um especialista nisso, mas recentemente me deparei com o que acho que você deseja: a classe de atributo CoClass .
Veja minha resposta a uma pergunta semelhante sobre a API do Microsoft Speech , onde você pode "instanciar" a interface
SpVoice
(mas, na verdade, você está instanciandoSPVoiceClass
).fonte
Entre você e Michael, você quase reuniu as peças. Eu acho que é assim que funciona. (Eu não escrevi o código, por isso posso estar indeciso, mas tenho certeza de que é assim que funciona.)
E se:
o código é gerado como (IPIAINTERFACE) Activator.CreateInstance (Type.GetTypeFromClsid (GUID OF COCLASSTYPE))
E se:
o código é gerado como se você tivesse dito "new COCLASSTYPE ()".
Jon, sinta-se à vontade para me incomodar ou Sam diretamente, se você tiver perguntas sobre essas coisas. Para sua informação, Sam é o especialista nesse recurso.
fonte
Ok, isso é apenas para dar um pouco mais de detalhe à resposta de Michael (ele pode adicioná-lo se quiser, caso em que removerei esse).
Observando o PIA original para Word.Application, existem três tipos envolvidos (ignorando os eventos):
Existem duas interfaces por razões que Eric Lippert fala em outra resposta . E, como você disse, existe o
CoClass
- tanto em termos da própria classe quanto do atributo naApplication
interface.Agora, se usarmos a ligação PIA em C # 4, parte disso será incorporada no binário resultante ... mas não em tudo. Um aplicativo que apenas cria uma instância de
Application
acaba com estes tipos:Não
ApplicationClass
- presumivelmente porque isso será carregado dinamicamente do tipo COM real no momento da execução.Outra coisa interessante é a diferença no código entre a versão vinculada e a versão não vinculada. Se você descompilar a linha
na versão referenciada , termina como:
enquanto que na versão vinculada termina como
Portanto, parece que o PIA "real" precisa do
CoClass
atributo, mas a versão vinculada não precisa, porque não existe umCoClass
compilador que possa realmente fazer referência. Tem que fazer isso dinamicamente.Eu posso tentar falsificar uma interface COM usando essas informações e ver se consigo o compilador vinculá-lo ...
fonte
Apenas para adicionar um pouco de confirmação à resposta de Michael:
O código a seguir compila e executa:
Você precisa do
ComImportAttribute
e doGuidAttribute
para que ele funcione.Observe também as informações ao passar o mouse sobre o
new IFoo()
: Intellisense capta corretamente as informações: Nice!fonte