我在C#中有一个单例使用LoadLibrary
,GetProcAddress
和FreeLibrary
来手动链接从非托管C ++ dll导出的多个函数。大多数对象的声明都是这样的:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate int Function_prototype(int someParams);
Function_prototype MyFunction;
public myFunction(int someParams)
{
return MyFunction(someParams);
}
//repeated many times with minor variations for each function
代理人使用类似的东西分配:
IntPtr dllHandle = LoadLibrary(@"C:\path\to\file.dll");
IntPtr addressToFunction = GetProcAddress(dllHandle, "MyFunction");
//error checking omitted to keep example brief
MyFunction = (MyFunction_Prototype)Marshal.GetDelegateForFunctionPointer(addressToFunction, typeof(MyFunction))
(注意:我提到我在下一段中有访问冲突异常。它们与上面的步骤无关,它似乎工作正常,并且代理在访问之前对该函数的许多调用都有效发生违规行为)
我们正在尝试诊断一些偶然的访问冲突异常,这些异常在调用其中一个函数时会不可预测地弹出。因此,我正在探索解决方案,以便在崩溃整个系统之前识别问题。 我看到了两种方法,我需要帮助找出如何实现其中任何一种方法,如果两者都有可能,那么我们将不胜感激。
1)有没有办法在调用函数之前检查委托是否不再有效?我可以修改上面myFunction
的定义更像是这样:
public myFunction(int someParams)
{
try
{
return MyFunction(someParams);
}
catch(AccessViolationException)
{
throw new UsefulErrorException();
}
}
但是添加到我正在导入的每个功能都会很乏味。我查看了Delegate文档,如果我在尝试调用它之前能够识别出MyFunction
无效,那么这对我来说并不明显。我想要这样的东西:
if(!MyFunction.IsValid())
throw new UsefulErrorException();
return MyFunction(someParams);
但写出数十次仍然是乏味的。是否有一种简单的方法可以告诉它在被调用之前会失败?
2)如果我必须满足于(1)中详述的try/catch
示例,那么有没有办法使它更通用,所以我不必重写那个try / catch几十次?它必须是通用的,我可以传入我的非托管委托,它的参数(没有params
,但它们包含许多不同的数字和类型的参数),以及各种返回类型(void
,{{ 1}},int
,IntPtr
,string
)。我觉得有一种通用的方法,否则这种情况会违反Don't Repeat Yourself。