Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#在调用前检查非托管函数指针是否安全 我在C++中使用了一个单独的代码,使用 LoadLibrary < />代码> GePosiald> < /C> >和 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)) public myFunction(int someParams) { try { return MyFunction(someParams); } catch(AccessViolationException) { throw new UsefulErrorException(); } }_C#_Delegates_Unmanaged - Fatal编程技术网

C#在调用前检查非托管函数指针是否安全 我在C++中使用了一个单独的代码,使用 LoadLibrary < />代码> GePosiald> < /C> >和 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)) public myFunction(int someParams) { try { return MyFunction(someParams); } catch(AccessViolationException) { throw new UsefulErrorException(); } }

C#在调用前检查非托管函数指针是否安全 我在C++中使用了一个单独的代码,使用 LoadLibrary < />代码> GePosiald> < /C> >和 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)) public myFunction(int someParams) { try { return MyFunction(someParams); } catch(AccessViolationException) { throw new UsefulErrorException(); } },c#,delegates,unmanaged,C#,Delegates,Unmanaged,并使用如下方式分配代理: [UnmanagedFunctionPointer(CallingConvention.Cdecl)] delegate int Function_prototype(int someParams); Function_prototype MyFunction; public myFunction(int someParams) { return MyFunction(someParams); } //repeated many times with minor

并使用如下方式分配代理:

[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))
public myFunction(int someParams)
{
   try
   {
       return MyFunction(someParams);
   }
   catch(AccessViolationException)
   {
       throw new UsefulErrorException();
   }
}
(注意:我在下一段中提到了访问冲突异常。它们与上述步骤无关,它似乎工作正常,并且在访问冲突发生之前,委托将对函数的多次调用有效)

我们正在尝试诊断一些偶尔出现的访问冲突异常,这些异常在调用其中一个函数时会意外出现。因此,我正在探索解决方案,以便在问题导致整个系统崩溃之前确定问题我看到两种方法,我需要帮助找出如何实现其中一种,如果两者都可行,请列出每种方法的优缺点。

1) 在调用函数之前,是否有方法检查委托是否不再有效?我可以修改上面的
myFunction
的定义,使其更像这样:

[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))
public myFunction(int someParams)
{
   try
   {
       return MyFunction(someParams);
   }
   catch(AccessViolationException)
   {
       throw new UsefulErrorException();
   }
}
但是,添加到我要导入的每个函数中会很乏味。我查看了文档,在我尝试调用它之前,如果我能确定
MyFunction
是无效的,这对我来说并不明显。我想要像这样的东西:

if(!MyFunction.IsValid())
    throw new UsefulErrorException();
return MyFunction(someParams);
但写几十遍仍然很乏味。有没有一种简单的方法可以在它被调用之前判断它是否会失败


2) 如果我必须满足于(1)中详述的
try/catch
示例,那么有没有办法让它更通用,这样我就不必重写几十次try/catch了?它必须具有足够的通用性,以便我可以传入非托管委托、其参数(无
params
,但它们包含许多不同数量和类型的参数)以及各种返回类型(
void
int
IntPtr
string
bool
)。我觉得有一种通用的方法,否则会有违规的味道。

这是不可能的,只要你尝试解决这个问题,它就不会再发生了。必须调用GCHandle.Alloc()以确保委托不能被垃圾收集。GC完全不知道本机代码正在使用它。请记住LoadLibrary+GetProcAddress有多痛苦,尽可能使用[DllImport]。这和我做的完全一样。@HansPassant
DllImport
不是一个选项,因为我工作的人设置了约束,否则我会是。我用它来引入
LoadLibrary
GetProcAddress
,和
freebrary
,但仅此而已。