How to control the execution of an externl native DLL

大憨熊 提交于 2019-12-12 07:00:36

问题


I have this code in .NET:

 result = NativeMethods.gsapi_init_with_args(_ghostScriptInstance, args.Length, _argumentPointersHandle.AddrOfPinnedObject());

That in its turn executes this code

[DllImport("C:\\gsdll64.dll", EntryPoint = "gsapi_init_with_args")]
public static extern int gsapi_init_with_args(IntPtr instance, int argc, IntPtr argv);

The problem is that because of yet unknown problem the native execution enters into an infinite loop and never returns.

The question is how can I cap the execution time of this native thing. Can I like tell .NET somehow that if NativeMethods.gsapi_init_with_args doesn't return within a minute then kill the native execution and return?


回答1:


Probably call the method in a new thread and kill the thread if the call does not complete in time. Killing thread is bad, but in this particular case I am assuming that you don't have access to the source code of the native function.

Somehow Thread.Abort does not work (will try to figure out how the interop threading stuff works), rather than creating a managed thread you can create a native thread using CreateThread and terminate it after a timeout.

[DllImport("Library.dll")]
public static extern void InfiniteLoop();

[DllImport("kernel32")]
private static extern int CreateThread(
   IntPtr lpThreadAttributes,
   UInt32 dwStackSize,
   IntPtr lpStartAddress,
   IntPtr param,
   UInt32 dwCreationFlags,
   UInt32 lpThreadId
 );

[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern int TerminateThread(int hThread);

[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]
public static extern int GetLastError();

private delegate int InvokeInfiniteLoop(IntPtr args);

static void Main(string[] args)
{
      InvokeInfiniteLoop invokeInfiniteLoop = (args1) =>
                                                    {
                                                        InfiniteLoop();
                                                        return 0;
                                                    };
     IntPtr infiniteLoopPtr = Marshal.GetFunctionPointerForDelegate(invokeInfiniteLoop);
     int handle = CreateThread(IntPtr.Zero, 0, infiniteLoopPtr, IntPtr.Zero, 0, 0);
     Thread.Sleep(TimeSpan.FromSeconds(5));
     int terminated = TerminateThread(handle);
     Console.WriteLine(terminated);
}

A word of caution, terminating thread is dangerous, you can read all about it here: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686717(v=vs.85).aspx. HansPassant is right, if the source is available you can debug it and figure out the bug.



来源:https://stackoverflow.com/questions/12022993/how-to-control-the-execution-of-an-externl-native-dll

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!