2010-02-17 2 views
3

Я сделал это, чтобы вызвать неуправляемую функцию из кода C. pCallback - это указатель на функцию, так что управляемая сторона является делегатом.Исключение C# при вызове функции обратного вызова

[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]. Я не понимаю, что это не так. Может кто-нибудь мне помочь?

ответ

1

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

[UnmanagedFunctionPointer(CallingConvention.xxx, CharSet = CharSet.xxx)] 
public delegate ... 
+0

Он работал !!! Большое спасибо! – jose

2

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

Тогда комп являются кодом ошибки в этом списке: http://msdn.microsoft.com/en-us/library/ms681381(VS.85).aspx

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

1

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

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

2

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

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

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

См here

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

Смежные вопросы