Pergunta

Eu estou fazendo referência uma estrutura COM que começa da seguinte forma:

[scriptable, uuid(ae9e84b5-3e2d-457e-8fcd-5bbd2a8b832e)]
interface nsICacheSession : nsISupports
{
    /**
     * Expired entries will be doomed or evicted if this attribute is set to
     * true.  If false, expired entries will be returned (useful for offline-
     * mode and clients, such as HTTP, that can update the valid lifetime of
     * cached content).  This attribute defaults to true.
     */
    attribute PRBool doomEntriesIfExpired;
...

Fonte: http : //dxr.proximity.on.ca/dxr/mozilla-central/netwerk/cache/public/nsICacheSession.idl.html#58

Eu encontrei código para importar essa interface em meu aplicativo C #. O código deve ser embora errado, como o método set não parece ser útil e também lança um erro quando tento chamá-lo só para ver o que acontece:

[Guid("ae9e84b5-3e2d-457e-8fcd-5bbd2a8b832e"), ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface nsICacheSession
{
    [return: MarshalAs(UnmanagedType.Bool)]
    void set_doomEntriesIfExpired();
    [return: MarshalAs(UnmanagedType.Bool)]
    bool get_doomEntriesIfExpired();
...

O que é a maneira correta para definir o valor de doomEntriesIfExpired e como faço referência a esse do meu código?

Editar

Eu mudei meu código para o seguinte, que produziu "System.AccessViolationException: Tentativa de ler ou protegido contra gravação Memória yada yada ...":

[Guid("ae9e84b5-3e2d-457e-8fcd-5bbd2a8b832e"), ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface nsICacheSession
{
    void set_doomEntriesIfExpired(bool enabled);
    bool get_doomEntriesIfExpired();
...
Foi útil?

Solução

A resposta você inseriu é bom. Em COM bools Interop são empacotados como VARIANT_BOOL por padrão, então sua adição do atributo MarshalAs para dizer o empacotador de usar um 4 byte tipo BOOL padrão é correto, embora a parte getter da equação precisa do atributo adicionado também.

Em geral, eu gostaria de deixar propriedades definidas na interface como propriedades em vez de quebrá-los para fora em seus getters e setters. Ele corresponde a semântica da definição de interface melhor e é geralmente mais fácil de ler também. Você deve ser capaz de voltar a escrever a sua definição de importação COM da seguinte forma para manter a natureza atributo de doomEntriesIfExpired:

[Guid("ae9e84b5-3e2d-457e-8fcd-5bbd2a8b832e"), ComImport, 
    InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface nsICacheSession
{

    bool doomEntriesIfExpired 
    { 
        [param:MarshalAs(UnmanagedType.Bool)]set; 
        [return:MarshalAs(UnmanagedType.Bool)]get; 
    }

...

Outras dicas

O fato de que você indicar um [return: MarshalAs(UnmanagedType.Bool)] para o seu método void set é, obviamente, uma fonte de erro.

Dito isso, eu consegui o código de um C ++ mozilla plugin sem o [retorno ...] tags no .idl, por exemplo:

[scriptable, uuid(ae9e84b5-3e2d-457e-8fcd-5bbd2a8b832e)]
interface nsICacheSession : nsISupports
{
    void set_doomEntriesIfExpired(in bool value);
    bool get_doomEntriesIfExpired();
}

A propósito, você tem certeza que pode codificar a NSI plugin no C #?

Acontece que a resposta foi a seguinte:

[Guid("ae9e84b5-3e2d-457e-8fcd-5bbd2a8b832e"), ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface nsICacheSession
{
    void set_doomEntriesIfExpired([In, MarshalAs(UnmanagedType.Bool)] ref bool enabled);
    bool get_doomEntriesIfExpired();
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top