У меня был фрагмент кода, который выдавал исключение в отношении делегата, собирающего мусор, вызываемого неуправляемой функцией. Это код:
// Setup Callback functions
errorCode = gsapi_set_stdio(ghostScriptPtr, new StdioMessageEventHandler(RaiseStdInCallbackMessageEvent), new StdioMessageEventHandler(RaiseStdOutCallbackMessageEvent), new StdioMessageEventHandler(RaiseStdErrCallbackMessageEvent));
if (errorCode >= 0)
{
try
{
//GC.SuppressFinalize(this);
// Init the GhostScript interpreter
errorCode = gsapi_init_with_args(ghostScriptPtr, commandParameters.Length, commandParameters);
// Stop the Ghostscript interpreter
gsapi_exit(ghostScriptPtr);
}
finally
{
// Release the Ghostscript instance handle
gsapi_delete_instance(ghostScriptPtr);
}
}
_Raise ... переменные, переданные в функцию, располагаются перед вызовом функцией.
Я не знаю, что со мной произошло, но я изменил обратные вызовы на переменные:
var _RaiseStdInCallbackMessageEventHandler = new StdioMessageEventHandler(RaiseStdInCallbackMessageEvent);
var _RaiseStdOutCallbackMessageEventHandler = new StdioMessageEventHandler(RaiseStdOutCallbackMessageEvent);
var _RaiseStdErrCallbackMessageEventHandler = new StdioMessageEventHandler(RaiseStdErrCallbackMessageEvent);
// Setup Callback functions
errorCode = gsapi_set_stdio(ghostScriptPtr, _RaiseStdInCallbackMessageEventHandler, _RaiseStdOutCallbackMessageEventHandler, _RaiseStdErrCallbackMessageEventHandler);
и, наконец, блокировать до:
finally
{
// Release the Ghostscript instance handle
gsapi_delete_instance(ghostScriptPtr);
_RaiseStdInCallbackMessageEventHandler = _RaiseStdOutCallbackMessageEventHandler = _RaiseStdErrCallbackMessageEventHandler = null;
}
и это решило проблему. Зачем? Я не знаю. Возможно, это просто совпадение. У меня есть ощущение, что использование переменных в блоке finally приводит к тому, что объект переменной не удаляется рано (поскольку он используется в блоке finally). Это правда? В любом случае, это правильный подход для предоставления функции dllimported с управляемыми обратными вызовами?
Спасибо, Pawel