2014-10-15 13 views
7

Ho sentito dire che Nullable<T> è una classe generica C# e non funziona con COM, come qualsiasi altra classe generica.In che modo un marshall del server COM annulla la libreria di classi C# con le diverse enumerazioni di ComInterfaceType?

Ebbene, nella mia libreria di classi C che ho:

[InterfaceType(ComInterfaceType.InterfaceIsDual), 
Guid("2FCEF713-CD2E-4ACB-A9CE-E57E7F51E72E")] 
public interface ICOMClass 
{ 
    int? GetNullable(); 
} 

[ClassInterface(ClassInterfaceType.None)] 
[Guid("57BBEC44-C6E6-4E14-989A-B6DB7CF6FBEB")] 
public class COMClass : ICOMClass 
{ 
    public int? GetNullable() 
    { 
     int? hello = null; 
     return hello; 
    } 
} 

Sorprendentemente che compila e io sono in grado di collegare i riferimenti alla mia biblioteca COMClass in VBE.

so che:

  • VBA fa non lista .GetNullable() nella lista dei membri sul Visualizzatore oggetti (anche con Mostra membri nascosti segno di spunta)
  • VBA fa non lista .GetNullable() in l'intelli-sense discesa

ma perché:

Dim c as new COMClass 
c.GetNullable 

fa non gettare un piuttosto atteso Object doesn't support this property or method?

in contrapposizione a:

c.NonExistingMethod 

Qualcuno può spiegare perché?

Sono sospetto che ha qualcosa a che fare con ComInterfaceType Enumeration perché

  • entrambi: InterfaceIsDual & InterfaceIsIDispatch atto proprio come ho descritto sopra

ma:

  • InterfaceIsIUnknown realtà non sembra maresciallo/tocco il GetNullable() e l'errore previsto è gettato ...

Qualcuno può spiegare questo comportamento?

+0

Guarda questo articolo http://www.codeproject.com/Articles/66244/Marshaling-with-C-Chapter-Marshaling-Simple-Type e fai una ricerca su '[Working with Nullable Arguments]' quando sono sulla pagina che spiegherà più in dettaglio .. – MethodMan

+0

@DJKRAZE grazie mille per il link però non ho trovato una spiegazione alla mia domanda: perché VBA consente una chiamata a un metodo che in realtà non è visibile da nessuna parte su la libreria COM? Sono lo sviluppatore di quella libreria quindi so che esiste e ho scoperto che VBA mi permette di chiamare 'c.GetNullable()' - sto solo chiedendo perché? Perché non è completamente nascosto ecc? –

+0

Quando si visualizza la libreria in Visualizzazione OLE, c'è qualche indicazione che il .tlb/.dll/qualunque sia nascosto nell'IDL di GetNullable? – Mike

risposta

2

Bene, si compila. Ma sai che hai problemi quando si tenta di creare una libreria di tipi per la DLL:

C:\projects2\ClassLibrary38\bin\Debug>tlbexp ClassLibrary38.dll 
Microsoft (R) .NET Framework Assembly to Type Library Converter 4.0.30319.33440 
Copyright (C) Microsoft Corporation. All rights reserved. 

TlbExp : warning TX8013117D : Type library exporter warning processing 'ICOMClas 
s.GetNullable(#0), ClassLibrary38'. Warning: Type library exporter encountered a 
generic type instance in a signature. Generic code may not be exported to COM. 
Assembly exported to 'C:\projects2\ClassLibrary38\bin\Debug\ClassLibrary38.tlb' 

Potete guardare eseguendo Oleview.exe sulla libreria dei tipi. Ecco come appare la tua interfaccia:

[ 
    odl, 
    uuid(2FCEF713-CD2E-4ACB-A9CE-E57E7F51E72E), 
    version(1.0), 
    dual, 
    oleautomation, 
    custom(0F21F359-AB84-41E8-9A78-36D110E6D2F9, "ICOMClass") 

] 
interface ICOMClass : IDispatch { 
}; 

Nulla, nada, zippo. I programmatori Microsoft a volte sono troppo amichevoli quando scrivono un messaggio diagnostico. Non è solo "non può essere", è "non sarà".

Questo non funzionerà.Che non riesca a trovare il metodo con il binding tardivo, il valore restituito non può essere interpretato correttamente, Nullable<T> non è [ComVisible]. In alternativa, considera che COM ha sempre avuto a che fare con il concetto di "nullability", fortemente supportato in VBA, che dipende molto da esso. Le varianti possono memorizzare vtNull o vtEmpty per indicare che un valore non è impostato. È oggetto nel codice C#.

+0

aha! Ancora non capisco come in realtà ** possa ** trovare il metodo poiché non esiste nel * '.tlb' *. È vero che * * .tlb' * è responsabile solo delle informazioni intelli-sense e Object Browser e * * .dll' * è accessibile direttamente? Come quando si aggiungono riferimenti a un file .NET nativo * '.dll' * e non è possibile visualizzare alcuni metodi nel Visualizzatore oggetti né intelli-sense ma è comunque possibile chiamare * (e non riuscire) * alcuni membri perché si sa che esistono a causa della familiarità con l'API? –

+1

VBA utilizza l'associazione tardiva come riserva, notare come l'interfaccia implementa IDispatch. Un po 'di difetto nel CLR, forse, potrebbe essere intenzionale. –

+0

Inoltre, non ho visto l'avviso per iniziare, poiché VS non ha visualizzato la finestra degli errori per me e non mi sono preoccupato di controllare gli avvisi (sì, so colpa mia !!). –