C # делегаты от переполнения стека

У меня следующая ситуация: библиотека C ++, которая «общается» с устройством ввода-вывода через последовательный порт. Библиотека C ++ выполняет некоторый опрос на устройстве, и когда ввод установлен, вызывается функция обратного вызова:

#if defined( _MSC_VER ) || defined( __MINGW32__ ) || defined( __MINGW64__ )
#   define LIB_CALLBACK __stdcall
#   define LIB_CALL __cdecl
#   if defined( LIB_EXPORTS )
#       define LIB_API __declspec( dllexport )
#   else
#       define LIB_API __declspec( dllimport )
#   endif
#else
#   define LIB_API
#endif // WIN32

#if defined( __cplusplus )
extern "C" {
#endif

typedef int libInput;
typedef void (* LIB_CALLBACK libOnInput )  ( libInput buttons );

LIB_API void LIB_CALL libRegisterInput( libInput f );

#if defined( __cplusplus )
}
#endif

Это функция потока

libOnInput g_libOnInputFunc = nullptr;

LIB_API void LIB_CALL libRegisterInput( libInput f )
{
libOnInputFunc = f;
}

// while true
if ( g_iocOnInputFunc )
{
libInput = // ...
// the event is called asyncronously. I don't want block the current thread
std::thread t( g_libOnInputFunc, in );
t.detach();
}

Теперь эта библиотека должна использоваться из приложения VB.net. Итак, я обернул свою библиотеку в C #

public delegate void OnInputDownDelegate(int input);

[DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern void libRegisterInput( OnInputDownDelegate f );

public void RegisterOnInput(OnButtonDownDel f)
{
libRegisterInput(f);
}

Теперь на Visual Basic я использую непосредственно библиотеку оболочки C #:

Imports CSharpLib

Public Class Form1Private Shared myLib As CSharpLib.CSharpLib

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
myLib = New CSharpLib.CSharpLib()
myLib.RegisterOnButtonDown(New CSharpLib.OnInputDownDelegate(AddressOf OnInput))
End Sub

Private Sub OnInput(ByVal input As Integer)
MessageBox.Show(input.ToString())
End Sub

End Class

Но когда я запускаю приложение, если я нажимаю кнопку на устройстве, mylib.dll ловит ввод и хочет вызвать функцию обратного вызова, но сбой приложения. Кажется, я звоню делегату по нулевой ссылке.

Это код ошибки:

Eccezione non gestita di tipo 'System.NullReferenceException' in Modulo sconosciuto.

Informazioni aggiuntive: Riferimento a un oggetto non impostato su un'istanza di oggetto.

В переводе это:

Exception of type 'System.NullReferenceException' in Unknown Module

Extra information: Reference to an object not setted on an object instance

0

Решение

Я должен сохранить ссылку на делегат, чтобы избежать того, что GC удалит ссылку на делегат:

public delegate void OnInputDownDelegate(int input);
private OnInputDownDelegate mDelegate;

[DllImport("mylib.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern void libRegisterInput( OnInputDownDelegate f );

public void RegisterOnInput(OnButtonDownDel f)
{
mDelegate = f;
libRegisterInput( mDelegate );
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector