2009-10-22 8 views
1

Je référence à une structure COM qui commence comme suit:PInvoke - comment représenter un champ à partir d'une interface COM

[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; 
... 

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

J'ai trouvé le code pour importer cette interface dans mon application C#. Le code doit être mauvais si, comme la méthode set ne semble pas être utile et jette aussi une erreur lorsque je tente de l'appeler juste pour voir ce qui se passe:

[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(); 
... 

Quelle est la bonne façon de régler la valeur de doomEntriesIfExpired et comment puis-je faire référence à partir de mon code?

EDIT

J'ai changé mon code pour ce qui suit, qui a produit "System.AccessViolationException: Tentative de lecture ou en écriture mémoire patata ...":

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

Répondre

3

La réponse que vous avez inséré est bon. Dans COM Interop bools sont marshalés comme VARIANT_BOOL par défaut, donc votre ajout de l'attribut MarshalAs pour indiquer au marshaleur d'utiliser un type BOOL standard de 4 octets est correct, bien que la partie getter de l'équation nécessite également l'attribut ajouté.

En général, j'aime laisser les propriétés définies dans l'interface comme des propriétés plutôt que de les décomposer en leurs getters et setters. Il correspond mieux à la sémantique de la définition de l'interface et est généralement plus facile à lire. Vous devriez être en mesure de ré-écrire votre définition d'importation COM comme suit pour conserver le caractère d'attribut 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; 
    } 

...

+0

Nice, je ne savais pas que vous pouviez conserver les propriétés lors de l'utilisation interop. –

1

Le fait que vous énoncez un [return: MarshalAs(UnmanagedType.Bool)] pour votre méthode void set est évidemment une source d'erreur.

Cela dit, je réussi à coder un C++ plug-in mozilla sans [...] retour balises dans le .idl, par exemple:

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

Par ailleurs, vous êtes sûr que vous pouvez coder un nsi plugin en C#?

+0

Je ne suis pas un plugin de codage SNI, je suis GeckoFX extension (http://geckofx.org) afin que je puisse accéder aux éléments du cache –

+0

Cela dit, comment votre code ci-dessus me permet-il de définir la valeur sur false? La méthode set que vous avez incluse n'inclut pas la valeur pour le mettre à ... –

+0

assez juste, j'ai fixé le setter (j'ai juste copié votre méthode et ai manqué ce point) – Vinzz

1

Transforme la réponse était la suivante:

[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(); 
Questions connexes