C # исключение при вызове функции обратного вызова - PullRequest
3 голосов
/ 17 февраля 2010

Я сделал это для вызова неуправляемой функции из кода Си. pCallback - это указатель на функцию, поэтому на управляемой стороне находится делегат.

[DllImport("MyDLL.dll")]

public static extern Result SetCallback(
            IntPtr handle,
            Delegate pCallback,
            CallbackType Type);

Сейчас я настраиваю

private delegate void pfnCallback(uint PromptID, ttsEventType evt, IntPtr lData);
private pfnCallback cb = new pfnCallback(cback);

public Form1()
{

    (...)
    Wrapper.SetCallback(handle, cb, IntPtr.Zero, CallBackType.DEFAULT);
    (...)
    public static void cback(uint PromptID, ttsEventType evt, IntPtr lData)
    { }
    }

При отладке я вижу, что она запускает функцию cback один раз, а затем я получаю исключение без данных, просто говоря «Произошло необработанное исключение win32 в WindowsApp2.vshost.exe [4372]. Я не понимаю, что неправильно. Кто-нибудь может мне помочь?

Ответы [ 4 ]

2 голосов
/ 17 февраля 2010

Здесь не так много деталей, но я думаю, что это может быть проблемой соглашения о вызовах. Я всегда пытаюсь явно установить соглашение о вызовах при использовании DllImport;

[DllImport("msvcrt.dll", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.Cdecl)]
public static extern int printf(String format, int i, double d); 

Соглашение о вызовах может влиять на то, как параметры помещаются в стек вызовов и как они очищаются после этого.

См. здесь

Вы должны найти правильное соглашение в заголовках или документах, поставляемых с вашей неуправляемой библиотекой.

2 голосов
/ 17 февраля 2010

Попробуйте вызвать Marshal.GetLastWin32Error (), чтобы получить код ошибки Win32.

Затем сравните код ошибки с этим списком: http://msdn.microsoft.com/en-us/library/ms681381(VS.85).aspx

Это все еще не так много информации, как хороший объект исключения, но он может указать вам правильное направление.

1 голос
/ 17 февраля 2010

Попробуйте использовать

[UnmanagedFunctionPointer(CallingConvention.xxx, CharSet = CharSet.xxx)]
public delegate ...
1 голос
/ 17 февраля 2010

Вы должны убедиться, что ваша ссылка на обратный вызов не собрана сборщиком мусора. Ссылка на обратный вызов должна быть активной в управляемой памяти до тех пор, пока ожидается обратный вызов.

Один из способов обойти это - создать слой Managed C ++ в середине

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...