0

我有以下情况:一个通过串行端口与 I/O 设备“对话”的 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 Form1


Private 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
4

1 回答 1

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 );
}
于 2013-09-04T11:10:18.893 回答