2014-10-15 21 views
7

Słyszałem, że Nullable<T> jest klasą ogólną C# i nie działa z COM - jak każda inna klasa ogólna.Jak serwer marszałek COM nullable w bibliotece klasy C# z różnych wyliczeń ComInterfaceType?

Cóż, w moim C# biblioteki klas mam:

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

Zaskakująco że kompiluje i jestem w stanie dołączyć referencje do mojego COMClass biblioteki w VBE.

wiem, że:

  • VBA robi nie listy .GetNullable() na liście członków na Object Browser (nawet z Pokaż ukryte członkowie zaznaczone)
  • VBA robi nie listy .GetNullable() w Intelli-sense drop down:

ale dlaczego:

Dim c as new COMClass 
c.GetNullable 

ma nie rzucać raczej spodziewać Object doesn't support this property or method?

w przeciwieństwie do:

c.NonExistingMethod 

Może ktoś wyjaśnić, dlaczego?

jestem podejrzliwy, że ma coś wspólnego z ComInterfaceType Enumeration ponieważ

  • zarówno: InterfaceIsDual & InterfaceIsIDispatch akcie jak opisałem powyżej

ALE:

  • InterfaceIsIUnknown faktycznie nie wydaje się być marszałkiem/dotykowyGetNullable() i spodziewany jest błąd ...

Może ktoś wyjaśnić to zachowanie?

+0

Spójrz na ten artykuł http://www.codeproject.com/Articles/66244/Marshaling-with-C-Chapter-Marshaling-Simple-Type i nie szukaj na '[Praca z pustych Argumenty]' Kiedy są na stronie, która wyjaśni bardziej szczegółowo. – MethodMan

+0

@DJKRAZE bardzo dziękuję za link, ale nie znalazłem wyjaśnienia na moje pytanie: dlaczego VBA pozwala na wywołanie metody, która w rzeczywistości nie jest widoczna nigdzie na biblioteka COM? Jestem programistą tej biblioteki, więc wiem, że istnieje i dowiedziałem się, że VBA pozwala mi wywoływać 'c.GetNullable()' - po prostu pytam dlaczego? Dlaczego nie jest całkowicie ukryty itp.? –

+0

Kiedy przeglądasz bibliotekę w OLE View, czy jest jakaś wskazówka, że ​​plik .tlb/.dll/cokolwiek ma GetNullable pochowany w IDL? – Mike

Odpowiedz

2

Cóż, kompiluje. Ale wiesz, że masz problemy podczas próby utworzenia biblioteki typów dla 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' 

Można spojrzeć na to przez uruchomienie OleView.exe na biblioteki typów. Oto, jak wygląda twój interfejs:

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

] 
interface ICOMClass : IDispatch { 
}; 

Nic, nada, zippo. Programiści Microsoft są czasami zbyt przyjaźni, gdy piszą komunikat diagnostyczny. To nie tylko "nie może być", ale "nie będzie".

To nie zadziała.To, że może znaleźć metodę późnym wiązaniem, nie pomoże, wartość zwracana nie może być poprawnie zinterpretowana, Nullable<T> nie jest [ComVisible]. Jako alternatywę należy wziąć pod uwagę, że COM zawsze musiała rozumieć "nullability", mocno wspieraną w VBA, która od tego zależy. Warianty mogą przechowywać vtNull lub vtEmpty, aby wskazać, że wartość nie jest ustawiona. Jest to obiekt w kodzie C#.

+0

aha! Nadal nie bardzo rozumiem, jak to jest możliwe ** może ** znaleźć metodę, ponieważ nie istnieje w * '.tlb' *. Czy to prawda, że ​​* '.tlb' * jest odpowiedzialny tylko za informacje wywiadowcze i informacje o przeglądarce obiektów, a *' .dll' * jest dostępny bezpośrednio? Podobnie jak przy dodawaniu referencji do natywnego .NET * '.dll' * i nie można zobaczyć niektórych metod w przeglądarce obiektów ani w intelli-sense, ale nadal możesz zadzwonić * (i nie udać się) * niektórzy członkowie sprawiają, że wiesz, że istnieją ze względu na znajomość API? –

+1

VBA używa późnego wiązania jako rezerwowego, zauważ, jak interfejs implementuje IDispatch. Może trochę luki w CLR może być celowe. –

+0

Dodatkowo, nie widziałem ostrzeżenia, aby zacząć, ponieważ VS nie wyświetlił okna błędów dla mnie i nie zawracałem sobie głowy sprawdzaniem ostrzeżeń (tak, znam moją winę !!). –