在调用之前,C#检查非托管函数指针是否安全

时间:2017-06-19 20:59:01

标签: c# delegates unmanaged

我在C#中有一个单例使用LoadLibraryGetProcAddressFreeLibrary来手动链接从非托管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}},intIntPtrstring)。我觉得有一种通用的方法,否则这种情况会违反Don't Repeat Yourself

0 个答案:

没有答案