Solucionando problemas de interoperabilidade

Quando você interoperar entre COM e o código gerenciado do .NET Framework, você pode encontrar um ou mais dos seguintes problemas comuns.

marshaling de interoperabilidade

Às vezes, talvez você precise usar tipos de dados que não fazem parte do .NET Framework. Assemblies de interoperabilidade lidar com a maior parte do trabalho para objetos COM, mas você pode ter que controlar os tipos de dados que são usados quando os objetos gerenciado são expostos para COM.Por exemplo, estruturas de bibliotecas de classes devem especificar o BStr tipo não gerenciado em seqüências de caracteres enviada para objetos COM criados pelo Visual Basic 6.0 e versões anteriores. Em tais casos, você pode usar o MarshalAsAttribute atributo para fazer com que tipos gerenciado a serem expostos sistema autônomo tipos não gerenciado.

Exportação de strings de comprimento fixo para código não gerenciado

No Visual Basic 6.0 e versões anteriores, sistema autônomo seqüências de caracteres são exportadas para objetos COM sistema autônomo seqüências de bytes sem um caractere de finalização nulo.Para compatibilidade com outras linguagens, Visual Basic 2005 inclui um caractere de finalização ao exportar as seqüências de caracteres. A melhor maneira de resolver essa incompatibilidade é exportar cadeias de caracteres que não têm o caractere de finalização sistema autônomo matrizes de Byte ou Char.

Exportação de hierarquias de herança

Gerenciado hierarquias nivelar check-out quando expostas sistema autônomo objetos COM de classe.Por exemplo, se você definir uma classe base com um membro e, em seguida, herda da classe base em uma classe derivada é exposta sistema autônomo um objeto COM, sistema autônomo clientes que usam a classe derivada no objeto COM não poderão usar sistema autônomo membros herdados.Membros de classe base podem ser acessados dos objetos COM somente sistema autônomo instâncias de uma classe base e, em seguida, somente se a classe base também é criada sistema autônomo um objeto COM.

Métodos sobrecarregados

Embora você possa criar métodos sobrecarregados com Visual Basic, eles não são suportados pelo COM. Quando uma classe que contém métodos sobrecarregados é exposta sistema autônomo um objeto COM, sistema autônomo novos nomes de método são gerados para métodos sobrecarregados.

Por exemplo, considere uma classe que tem duas sobrecargas do Synch método. Quando a classe for exposta sistema autônomo um objeto COM, sistema autônomo novos nomes de método gerado podem ser Synch e Synch_2.

A renomeação pode causar problemas de dois para os consumidores do objeto COM.

  1. Clientes não podem esperar que os nomes de método gerado.

  2. sistema autônomo nomes de método gerado na classe exposto sistema autônomo um objeto COM podem ser alterada quando novas sobrecargas são adicionadas à classe ou sua classe base.Isso pode causar problemas de controle de controle de versão.

Para solucionar sistema autônomo dois problemas, dar a cada método um nome exclusivo, em vez de usar a sobrecarga, quando você desenvolve objetos que serão expostos sistema autônomo objetos COM.

Uso de objetos COM através de assemblies de interoperabilidade

Você pode usar assemblies de interoperabilidade quase sistema autônomo se fossem substituições de código gerenciado para sistema autônomo objetos COM que eles representam.No entanto, como eles são wrappers e objetos COM não real, existem algumas diferenças entre usar assemblies de interoperabilidade e assemblies padrão.Essas áreas de diferença incluem a exposição de classes e tipos de dados para parâmetros e valores de retorno.

Classes expostos sistema autônomo ambas sistema autônomo interfaces e classes

Diferentemente das classes em módulos (assemblies) padrão, classes COM são expostas no sistema autônomo uma interface e uma classe que representa a classe COM assemblies de interoperabilidade.Nome da interface é idêntico da classe COM.O nome do clsistema autônomos interoperabilidade é o mesmo sistema autônomo que o original clsistema autônomos COM, mas com a palavra "Clsistema autônomos" acrescentado.Por exemplo, suponha que você tenha um projeto com uma referência para um assembly de interoperabilidade para um objeto COM.Se a classe COM é denominada MyComClassIntelliSense e o navegador objeto mostram uma interface denominada MyComClass e uma classe chamada MyComClassClass.

Criar instâncias de uma classe do estrutura .NET

Em geral, você criar uma instância de um .NET Framework classe usando o New demonstrativo com um nome de classe. Ter uma classe COM representado por um assembly de interoperabilidade é um caso no qual você pode usar o New demonstrativo com uma interface. A menos que você esteja usando a classe COM um Inherits demonstrativo, você pode usar a interface sistema autônomo faria com uma classe. O código a seguir demonstra como criar um Command objeto em um projeto tem uma referência para o Microsoft ActiveX dados Objects 2.8 biblioteca objeto COM:

Dim cmd As New ADODB.Command

No entanto, se você estiver usando a classe COM sistema autônomo base para uma classe derivada, você deve usar a classe de interoperabilidade que representa a classe COM, sistema autônomo no código a seguir:

Class DerivedCommand
    Inherits ADODB.CommandClass
End Class
Observação:

Assemblies de interoperabilidade implicitamente implementam interfaces que representam classes COM.Você não deve Tente Para usar o Implements Isso resultará em demonstrativo para implementar essas interfaces ou um erro.

Tipos de dados para parâmetros e valores de retorno

Ao contrário dos membros de módulos (assemblies) padrão, os membros do assembly de interoperabilidade podem ter tipos de dados que diferem daquelas usadas na declaração do objeto original.Embora assemblies de interoperabilidade convertem implicitamente tipos COM compatível tipos do common linguagem runtime, você deve prestar atenção para os tipos de dados que são usados por ambos os lados para evitar erros de tempo de execução.Por exemplo, em objetos COM criados no Visual Basic 6.0 e versões anteriores, os valores do tipo Integer Suponha que o .NET Framework tipo equivalente, Short. É recomendável que você use o Pesquisador objeto para examinar as características dos membros importados antes de usá-los.

Métodos COM nível de módulo

A maioria dos objetos COM são usados por criar uma ocorrência de uma classe COM usando o New palavra-chave e, em seguida, chamar métodos do objeto. Uma exceção a essa regra envolve objetos COM que contêm AppObj ou GlobalMultiUse COM classes. Essas classes semelhantes aos métodos de nível de módulo em Visual Basic 2005 classes. Visual Basic 6.0 e versões anteriores implicitamente criam instâncias de objetos para você na primeira vez que você telefonar um dos seus métodos.Por exemplo, no Visual Basic 6.0 você pode adicionar uma referência ao Microsoft DAO 3.6 biblioteca de objetos e chamar o DBEngine método sem primeiro criar uma instância:

Dim db As DAO.Database
' Open the database.
Set db = DBEngine.OpenDatabase("C:\nwind.mdb")
' Use the database object.

Visual Basic 2005 requer que você sempre criar instâncias de objetos COM que você possa usar seus métodos. Para usar esses métodos em Visual Basic 2005, declare uma variável de classe desejada e usar a nova palavra-chave para atribuir o objeto para a variável de objeto. The Shared palavra-chave pode ser usado quando você deseja se certificar de que apenas uma instância da classe é criada.

' Class level variable.
Shared DBEngine As New DAO.DBEngine

Sub DAOOpenRecordset()
    Dim db As DAO.Database
    Dim rst As DAO.Recordset
    Dim fld As DAO.Field
    ' Open the database.
    db = DBEngine.OpenDatabase("C:\nwind.mdb")

    ' Open the Recordset.
    rst = db.OpenRecordset( _
        "SELECT * FROM Customers WHERE Region = 'WA'", _
        DAO.RecordsetTypeEnum.dbOpenForwardOnly, _
        DAO.RecordsetOptionEnum.dbReadOnly)
    ' Print the values for the fields in the debug window.
    For Each fld In rst.Fields
        Debug.WriteLine(fld.Value.ToString & ";")
    Next
    Debug.WriteLine("")
    ' Close the Recordset.
    rst.Close()
End Sub

Erros sem tratamento no evento manipuladores

Um problema de interoperabilidade comum envolve erros no evento manipuladores que manipulam evento s elevado por objetos COM.Esses erros são ignorados, a menos que você verifique especificamente erros usando deOn Error ou Try...Catch...Finally instruções. Por exemplo, o exemplo a seguir é de um Visual Basic 2005 projeto tem uma referência ao objeto Microsoft ActiveX dados Objects 2.8 biblioteca COM.

' To use this example, add a reference to the 
'     Microsoft ActiveX Data Objects 2.8 Library  
' from the COM tab of the project references page.
Dim WithEvents cn As New ADODB.Connection
Sub ADODBConnect()
    cn.ConnectionString = _
    "Provider=Microsoft.Jet.OLEDB.4.0;" & _
    "Data Source=C:\NWIND.MDB"
    cn.Open()
    MsgBox(cn.ConnectionString)
End Sub

Private Sub Form1_Load(ByVal sender As System.Object, _
    ByVal e As System.EventArgs) Handles MyBase.Load

    ADODBConnect()
End Sub

Private Sub cn_ConnectComplete( _
    ByVal pError As ADODB.Error, _
    ByRef adStatus As ADODB.EventStatusEnum, _
    ByVal pConnection As ADODB.Connection) _
    Handles cn.ConnectComplete

    '  This is the event handler for the cn_ConnectComplete event raised 
    '  by the ADODB.Connection object when a database is opened.
    Dim x As Integer = 6
    Dim y As Integer = 0
    Try
        x = CInt(x / y) ' Attempt to divide by zero.
        ' This procedure would fail silently without exception handling.
    Catch ex As Exception
        MsgBox("There was an error: " & ex.Message)
    End Try
End Sub

Este exemplo gerará um erro conforme o esperado.No entanto, se você experimentar o mesmo exemplo sem o Try...Catch...Finally bloco, o erro será ignorado sistema autônomo se você usou o OnError Resume Next demonstrativo. Sem tratamento de erro, a divisão por zero falhará silenciosamente.Como tais erros nunca geram erros de exceção sem tratamento, é importante que você usar alguma forma de manipuladores de eventos que tratam os eventos dos objetos COM de manipulação de exceção.

Noções básicas sobre erros de interoperabilidade com.

Sem erro chamadas interop manuseio freqüentemente geram erros que fornecem informações pouco.Sempre que possível, use para fornecer mais informações sobre problemas quando eles ocorrerem de tratamento de erro estruturado.Isso pode ser especialmente útil quando você depurar aplicativos.Por exemplo:

Try
    ' Place call to COM object here.
Catch ex As Exception
    ' Display information about the failed call.
End Try

Você pode encontrar informações, sistema autônomo fonte de erros COM, HRESULT e a descrição do erro examinando o Sumário do objeto de exceção.

Problemas de controle ActiveX do ActiveX

A maioria dos controles ActiveX que funcionam com o Visual Basic 6.0 trabalhar com Visual Basic 2005 sem problemas. As principais exceções são controles de contêiner ou controles que contêm outros controles visualmente.Alguns exemplos de controles mais antigos que não funcionam corretamente com Visual Studio são sistema autônomo seguintes:

  • Controle quadro do Microsoft Forms 2.0

  • Controle para cima e para baixo, também conhecido sistema autônomo o controle de rotação

  • Controle da guia Sheridan

Há apenas soluções alternativas alguns problemas de controle ActiveX não suportado.Você pode migrar os controles existentes para Visual Studio Se você possui o código-fonte original. Caso contrário, você pode verificar com fornecedores de software para versões compatível com o .NET atualizadas dos controles para substituir os controles ActiveX sem suporte.

Passagem ReadOnly propriedades de controles ByRef

Visual Basic 2005às vezes gera erros de COM, sistema autônomo "Erro 0x800A017F CTL_E_SETNOTSUPPORTED" ao passar ReadOnly Propriedades de alguns controles ActiveX antigos sistema autônomo ByRef parâmetros para outros procedimentos. Chamadas de procedimento semelhante do Visual Basic 6.0 não aumente um erro e sistema autônomo parâmetros são tratados sistema autônomo se você passou pelo valor.A mensagem de erro que você vê no Visual Basic 2005 o objeto COM relata que está tentando alterar uma propriedade que não tem uma propriedade Set procedimento.

Se você tiver acesso ao procedimento que está sendo chamado, é possível evitar esse erro, usando o ByVal palavra-chave para declarar parâmetros aceitar ReadOnly Propriedades. Por exemplo:

Sub ProcessParams(ByVal c As Object)
    'Use the arguments here.
End Sub

Se você não tiver acesso ao código-fonte para o procedimento que está sendo chamado, você poderá forçar a propriedade a serem passados por valor, adicionando um conjunto extra de procedimento de chamada entre colchetes.Por exemplo, em um projeto tem uma referência ao objeto Microsoft ActiveX dados Objects 2.8 biblioteca COM, você pode usar:

Sub PassByVal(ByVal pError As ADODB.Error)
    ' The extra set of parentheses around the arguments
    ' forces them to be passed by value.
    ProcessParams((pError.Description))
End Sub

Implantar assemblies que exponha Interop

Implantar assemblies que expõem interfaces com. apresenta alguns desafios únicos.Por exemplo, um possível problema ocorre quando o mesmo assembly COM faz referência a aplicativos separados.Essa situação é comum quando uma nova versão de um assembly é instalada e outro aplicativo ainda está usando a versão antiga do assembly.Se você desinstalar um assembly que compartilha uma DLL, você pode, inadvertidamente, torná-lo não disponível para outros assemblies.

Para evitar esse problema, você deve instalar assemblies compartilhados para o global cache de assemblies (GAC) e use um MergeModule do componente.Se você não pode instalar o aplicativo no GAC, ele deverá ser instalado para CommonFilesFolder em um subdiretório específico da versão.

Os assemblies que não são compartilhados devem estar localizados lado a lado no diretório com o aplicativo de chamada.

Consulte também

Tarefas

Demonstra Passo a passo: Implementar herança com objetos COM

Conceitos

Alterações nos tipos de dados para usuários do Visual Basic 6.0

Introdução ao mesclar módulos

Mesclar módulo de projetos

Cache global de assemblies

Referência

MarshalAsAttribute

Tipo Biblioteca Importer (Tlbimp.exe)

Tipo Biblioteca Exporter (Tlbexp.exe)

Declaração Inherits

Outros recursos

Interoperabilidade COM

Interop Marshaling