Compartilhar via


Empacotamento de parâmetro do Assembly Interop Visual Studio

VSPackages são escritos em código gerenciado pode ter que chamar ou ser chamado pelo código COM não gerenciado. Normalmente, os argumentos do método são transformados ou empacotados, automaticamente pelo empacotador de interoperabilidade. No entanto, algumas vezes argumentos não podem ser transformados de forma direta. Nesses casos, os parâmetros de protótipo do método assembly de interoperabilidade são usados para corresponder os parâmetros da função COM possível. Para obter mais informações, consulte Realizando marshaling de interoperabilidade.

Sugestões gerais

Leia a documentação de referência

Leia a documentação de referência para cada método é uma maneira eficaz para detectar problemas de interoperabilidade.

A documentação de referência para cada método contém três seções relevantes:

  • O Visual C++ protótipo de função do COM.

  • O protótipo do método assembly de interoperabilidade.

  • Uma lista dos parâmetros COM e uma breve descrição de cada um.

Procure as diferenças entre os dois protótipos

A maioria dos problemas de interoperabilidade derivam de incompatibilidades entre a definição de um tipo específico em uma interface COM e a definição do mesmo tipo de Visual Studio assemblies de interoperabilidade. Por exemplo, considere a diferença na capacidade de passar um null valor em um parâmetro [out]. Você deve procurar as diferenças entre os dois protótipos e considerar suas ramificações para os dados passados.

Leia as definições de parâmetro

Leia as definições de parâmetro. COM é menos estrita que o common language runtime (CLR) sobre a mistura de diferentes tipos de dados em um único parâmetro. O Visual Studio interfaces COM aproveitarem essa flexibilidade. Qualquer parâmetro que pode passar ou exigem um valor não-padrão ou o tipo de dados, como, por exemplo, um valor constante em um parâmetro de ponteiro, deve ser descrito como tal na documentação.

IUnknown objetos passados como tipo void **

Procure [os parâmetros que são definidos como tipo out] void ** no COM a interface, mas que são definidos como [iid_is] na Visual Studio protótipo do método assembly de interoperabilidade.

Às vezes, uma interface COM gera um IUnknown objeto e a interface COM passá-lo como tipo de void **. Essas interfaces são especialmente importantes porque se a variável for definida como [out] no IDL, em seguida, a IUnknown o objeto é contado de referência com o AddRef método. Um vazamento de memória ocorre se o objeto não é tratado corretamente.

Dica

Um IUnknown o objeto criado pela interface COM e retornados em uma variável [out] faz com que um vazamento de memória se não for liberado explicitamente.

Métodos que lidam com esses objetos gerenciados devem tratar IntPtr como um ponteiro para um IUnknown de objeto e, em seguida, chame o GetObjectForIUnknown método para obter o objeto. O chamador, em seguida, deve converter o valor de retorno para qualquer tipo é apropriado. Quando o objeto não é mais necessário, chame Release para liberá-lo.

A seguir é um exemplo de chamada a QueryViewInterface método e o tratamento a IUnknown objeto corretamente:

    MyClass myclass;
    Object object;
    IntPtr pObj;
    Guid iid = Typeof(MyClass).Guid;
    int hr = windowFrame.QueryViewInterface(ref iid, out pObj);   
    if (NativeMethods.Succeeded(hr)) 
    {
        try 
        {
            object = Marshal.GetObjectForIUnknown(pObj);
            myclass = object;
        }
        finally 
        {
            Marshal.Release(pObj);
        }
    }
    else 
    {
        // error calling QueryViewInterface
    }

Dica

Os métodos a seguir são conhecidos por passar IUnknown ponteiros de objeto como tipo de IntPtr.Lidar com eles conforme descrito nesta seção.

Opcional [parâmetros out]

Procure os parâmetros que são definidos como [out] tipo de dados (int, objecte assim por diante) no COM a interface, mas que são definidos como matrizes do mesmo tipo de dados na Visual Studio protótipo do método assembly de interoperabilidade.

Alguns COM interfaces, como GetCfgs, tratar [out] parâmetros como opcionais. Se um objeto não for necessário, retornam dessas interfaces COM uma null o ponteiro como o valor desse parâmetro, em vez de criar o objeto [out]. Isso ocorre por design. Para essas interfaces, null ponteiros são considerados como parte do comportamento correto do VSPackage e nenhum erro será retornado.

Porque o CLR não permite que o valor de um parâmetro [out] para ser null, parte do que o comportamento padrão dessas interfaces não está disponível diretamente no código gerenciado. O Visual Studio métodos de assembly de interoperabilidade para interfaces afetados contornar o problema, definindo os parâmetros relevantes como matrizes, pois o CLR permite a passagem de null arrays.

Gerenciado implementações dos métodos a seguir devem colocar um null matriz no parâmetro quando não há nada a ser retornado. Caso contrário, crie uma matriz de um elemento do tipo correto e colocar o valor de retorno na matriz.

Gerenciado métodos que recebem informações de interfaces com opcional [out] parâmetros recebem o parâmetro como uma matriz. Basta examine o valor do primeiro elemento da matriz. Se não for null, trate o primeiro elemento, como se fosse o parâmetro original.

Constantes de passagem nos parâmetros de ponteiro

Procure os parâmetros que são definidas como [in] ponteiros na interface COM, mas que são definidos como um IntPtr digite o Visual Studio protótipo do método assembly de interoperabilidade.

Um problema similar ocorre quando passa de uma interface COM um valor especial, como, por exemplo, 0, -1 ou 2, em vez de um ponteiro de objeto. Ao contrário do Visual C++, o CLR não permite constantes ser convertido como objetos. Em vez disso, o Visual Studio assembly de interoperabilidade define o parâmetro como um IntPtr tipo.

Gerenciado implementações dos métodos a seguir devem aproveitar o fato de que o IntPtr classe tem ambos int e void * construtores para criar um IntPtr de um objeto ou uma constante de inteiro, conforme apropriado.

Gerenciado métodos que recebem IntPtr parâmetros desse tipo devem usar o IntPtr digite operadores de conversão para manipular os resultados. Converta primeiramente a IntPtr para int e testá-lo em constantes de inteiro relevantes. Se não há valores coincidirem, convertê-lo em um objeto do tipo necessário e continue.

Para obter exemplos disto, consulte OpenStandardEditor e OpenSpecificEditor.

OLE retornar valores passados como [parâmetros out]

Procure métodos que possuem um retval valor de retorno na interface COM, mas que têm um int retornar valor e um [parâmetro de matriz no out] adicionais a Visual Studio protótipo do método assembly de interoperabilidade. Deve estar claro que esses métodos exigem tratamento especial, pois o Visual Studio protótipos de método de assembly de interoperabilidade tem um parâmetro de mais que os métodos de interface COM.

Várias interfaces COM que lidam com a atividade OLE enviar informações sobre o status OLE volta para o programa de chamada armazenado na retval retornar o valor da interface. Em vez de usar um valor de retorno, o correspondente Visual Studio métodos de assembly de interoperabilidade enviar as informações de volta para o programa de chamada armazenado em um [out] parâmetro de matriz.

Gerenciado implementações dos métodos a seguir devem criar uma matriz de elemento único do mesmo tipo como o parâmetro [out] e colocá-lo no parâmetro. O valor do elemento da matriz deve ser o mesmo que o apropriado COM retval.

Métodos gerenciados que chamam as interfaces deste tipo devem obter o primeiro elemento de matriz [out]. Esse elemento pode ser tratado como se fosse um retval valor de retorno da interface COM correspondente.

Consulte também

Tarefas

Solucionando problemas de interoperabilidade (Visual Basic)

Outros recursos

Interop Marshaling

Realizando marshaling de interoperabilidade

VSPackages gerenciados