Como: Usar servidores COM nativo com CRCWs
Ao contrário de outras linguagens. NET, Visual C++ fornece recursos de interoperabilidade que permitem que APIs não gerenciadas, incluindo interfaces COM, a ser acessado diretamente e totalmente integrada.Para interoperabilidade COM em particular, isso oferece vantagens poderosas.
Exemplo
Como no exemplo em Como: Usar servidores COM nativo com TLBIMP, este exemplo usa as interfaces COM definidos Quartz.dll (encontrados na C:\window\System32 diretório) para executar arquivos AVI. No entanto, nesse caso, a interoperabilidade de C++ é usada em vez de um assembly de interoperabilidade separado gerado com Tlbimp.exe.Há várias vantagens dessa técnica.Nesse caso o código de interoperabilidade é incorporado ao aplicativo, portanto não há nenhuma dependência em um assembly separado.Além disso, o expostos gerenciado interface é personalizado para ser mais semelhante ao .NET.Por exemplo, o método RenderFile usa um sistema.String em vez de um char *.A versão gerenciada da interface COM é chamada uma personalizada tempo de execução Callable Wrapper (CRCW).
Gravar CRCWs não requer um assembly de interoperabilidade, mas exige arquivos de cabeçalho que definem as interfaces COM.Para componentes COM que incluem bibliotecas de tipos, esses cabeçalhos podem ser gerados usando a MIDL Compiler.
A primeira parte do exemplo de código a seguir define o wrapper personalizado, que expõe os membros que serão apresentados ao aplicativo gerenciado.A segunda parte é um aplicativo de console pelo wrapper personalizado para executar arquivos AVI.
executar o arquivo .exe resultante com o nome de um arquivo AVI válido e o arquivo é processado em uma janela.
// use_native_COM_servers_with_CRCWs.cpp
// compile with: /clr
// processor: x86
#include <comdef.h>
#import "quartz.tlb" no_namespace
using namespace System;
using namespace System::Runtime::InteropServices;
//_COM_SMARTPTR_TYPEDEF(IMediaControl, IID_IMediaControl);
ref struct Player : public IDisposable {
Player() : fm((new IMediaControlPtr())) {
fm->CreateInstance(__uuidof(FilgraphManager), 0, CLSCTX_INPROC_SERVER);
if ((*fm) == 0)
throw gcnew Exception("Could not create COM object");
}
~Player() {
this->!Player();
}
!Player() {
(*fm).Release();
delete fm;
}
void RenderFile(String^ file) {
IntPtr ip = Marshal::StringToBSTR(file);
BSTR b = static_cast<BSTR>(ip.ToPointer());
(*fm)->RenderFile(b);
Marshal::FreeBSTR(ip);
}
void Run() {
(*fm)->Run();
}
private:
IMediaControlPtr* fm;
};
void DisplayUsage() {
Console::WriteLine("AVIPlayer2: Plays AVI files.");
Console::WriteLine("Usage: AVIPlayer2.EXE <filename>");
}
int main() {
array<String^>^ args = Environment::GetCommandLineArgs();
if (args->Length != 2) {
DisplayUsage();
return 0;
}
String^ filename = args[1];
if (filename->Equals("/?")) {
DisplayUsage();
return 0;
}
Player^ player = gcnew Player;
player->RenderFile(filename);
player->Run();
Console::WriteLine("press any key");
Console::ReadLine();
}