0

我有一些代码:

private static st_createInstance        createInstance;
private static st_destroyInstance       destroyInstance;
private static st_getVersionId          getVersionId;
private static st_getVersionString2     getVersionString2;

//...

[UnmanagedFunctionPointer (CallingConvention.StdCall)]
private delegate IntPtr st_createInstance ();

[UnmanagedFunctionPointer (CallingConvention.StdCall)]
private delegate void st_destroyInstance (IntPtr pHandle);

//...

现在如何使用反射使所有这些委托为空?(Idk 如何将字段与委托类型进行比较)。

编辑:我想以简单的方式将它们全部归零,比如 foreach 循环。不想指定每个字段名称。

4

2 回答 2

2

如果type是委托字段所在的对象类型,请尝试以下操作:

var fields = type.GetFields(BindingFlags.Static | BindingFlags.NonPublic);

fields = fields.Where(f => f.FieldType.BaseType == typeof(System.MulticastDelegate));

foreach (FieldInfo fi in fields)
{
    fi.SetValue(null, null);
}

第一个表示它nullSetValue一个静态字段,第二个是用于将字段的值设置为null.

于 2013-07-24T21:25:45.020 回答
1

这强烈暗示了一个 XY 问题。当 OP 没有解释他为什么需要做某事时,这总是一个问题。当您尝试执行 pinvoke marshaller 使用 [DllImport] 属性执行的工作时,您将编写此类代码。

如果这完全正确,那么请注意,将这些委托对象设置回 null 没有什么意义,即使它们是静态的。它们实际上指的是thunk,即在非托管代码和托管代码之间编组的一小段自动生成的代码。通常它只不过是一条简单的 JMP 指令,当需要重新调整堆栈帧时,它会变得更加复杂。

委托对象本身需要少量的 GC 堆,只有 32 个字节。您将希望避免编写使用反射来摆脱约 36 个字节的代码,这在时间或空间上都没有回报。代码已经比你释放的内存大了。更不用说真正的成本,你维护这个代码。

考虑去掉初始化这些委托的代码。几乎从不需要,pinvoke marshaller 已经非常擅长自己做这件事。您只需要帮助它找出在哪里可以找到 DLL,有使用 LoadLibrary() 更好的方法。例如检查这个答案

于 2013-07-24T21:51:46.323 回答