Я пытаюсь написать немного кода (только для домашнего использования), который использует UPnP для обхода NAT, используя С# 4 и Microsoft COM-based NAT API обхода (Hnetcfg.dll).
К сожалению (или, возможно, к счастью), последний раз, когда мне приходилось делать COM-взаимодействие в .NET, было что-то около последнего ледникового периода, и я, похоже, в основном смущен тем, что С# использует динамические типы для взаимодействия и как писать обратный вызов (так что COM-сервер вызывает мой управляемый код).
Здесь несколько захватывающих строк кода:
// Referencing COM NATUPNPLib ("NATUPnP 1.0 Type Library")
using System;
using NATUPNPLib;
class NATUPnPExample
{
public delegate void NewNumberOfEntriesDelegate(int lNewNumberOfEntries);
public static void NewNumberOfEntries(int lNewNumberOfEntries)
{
Console.WriteLine("New number of entries: {0}", lNewNumberOfEntries);
}
public static void Main(string[] args)
{
UPnPNAT nat = new UPnPNAT();
NewNumberOfEntriesDelegate numberOfEntriesCallback = NewNumberOfEntries;
nat.NATEventManager.NumberOfEntriesCallback = numberOfEntriesCallback;
nat.StaticPortMappingCollection.Add(4555, "TCP", 4555, "192.168.0.1", true, "UPnPNAT Test");
// Presumably my NewNumberOfEntries() method should be called by the COM component about now
nat.StaticPortMappingCollection.Remove(4555, "TCP");
}
}
В приведенном выше коде вызовы Add and Remove работают абсолютно нормально. Потрясающе.
Проблема заключается в том, что я хотел бы знать, когда изменилось количество записей сопоставления портов, и для этого мне нужно зарегистрировать интерфейс обратного вызова (INATEventManager:: put_NumberOfEntriesCallback), который должен поддерживать интерфейсы INATNumberOfEntriesCallback или IDispatch. Объектный браузер VS2012 описывает INATEventManager:: put_NumberOfEntriesCallback таким образом:
dynamic NumberOfEntriesCallback { set; }
Правильно, поэтому у меня создалось впечатление, что в С# 4 мне не нужно ничего украшать с помощью причудливых атрибутов и что я могу зарегистрировать свой обратный вызов, просто поместив делегата в INATEventManager:: put_NumberOfEntriesCallback вульгарным способом и уйдя. NET, чтобы беспокоиться о IDispatch и очистить беспорядок; но кажется, что я ужасно ошибаюсь.
Итак, er... Что мне делать, чтобы вызывать метод NewNumberOfEntries?
Я также немного обеспокоен тем, что я могу написать nat.NATEventManager.NumberOfEntriesCallback = 1;
или nat.NATEventManager.NumberOfEntriesCallback = "Sausages";
без исключения исключения.