我正在尝试使用 C# 4 和 Microsoft 基于 COM 的NAT 遍历 API (Hnetcfg.dll)编写一些使用 UPnP 进行 NAT 遍历的代码(仅供家庭使用)。
不幸的是(或者幸运的是)我最后一次必须在 .NET 中进行 COM 互操作是在最后一个冰河时代左右,我似乎对 C# 使用动态类型进行互操作以及如何编写回调从根本上感到困惑(这样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 和 Remove 调用工作得很好。了不起。
麻烦的是,我还想知道端口映射条目的数量什么时候发生了变化,为此我需要注册一个回调接口(INATEventManager::put_NumberOfEntriesCallback),它必须支持 INATNumberOfEntriesCallback 或 IDispatch 接口。VS2012 的对象浏览器是这样描述 INATEventManager::put_NumberOfEntriesCallback 的:
dynamic NumberOfEntriesCallback { set; }
是的,所以我的印象是,在 C# 4 中,我不应该用花哨的属性来装饰任何东西,我可以通过将委托以粗俗的方式插入 INATEventManager::put_NumberOfEntriesCallback 并让 .NET 担心来注册我的回调关于 IDispatch 并收拾残局;但看来我大错特错了。
所以,呃......我应该怎么做才能确保调用我的 NewNumberOfEntries 方法?
我也有点担心我可以写nat.NATEventManager.NumberOfEntriesCallback = 1;
或nat.NATEventManager.NumberOfEntriesCallback = "Sausages";
不抛出异常。