我正在使用C ++编写JNI DLL,为我们的Java应用程序提供访问Windows 10和macOS上的蓝牙LE设备的方法。它使用C ++ / CX访问Windows 10和Objective-C ++上的蓝牙LE对象,以访问macOS上的等效对象。这个问题集中在我在Windows 10上遇到的崩溃,但是,因此不会考虑特定于macOS的代码。当通过JNI或通过单独的C导出使用我的DLL时(使用命令行测试应用程序我发生此崩溃)写道以简化调试。)
注意:for
是CentralManagerCppCxShim
,只有在事件被触发时才会回调ref class
。
当扫描正在运行时CentralManagerImpl
对象被销毁(即CentralManagerImpl
被调用)时发生崩溃:当StartScan()
被破坏时,它崩溃(我是否将其设置为{{ 1}}或者没有区别)。我与_deviceWatcher
有类似的问题,但正确删除析构函数中的事件处理程序使得崩溃消失了。
代码摘录:
CentralManagerImpl.h:
nullptr
CentralManagerImpl.cpp:
BluetoothLEAdvertisementWatcher
这是我得到的调用堆栈(是的,它很讨厌):
class CentralManagerImpl: public CentralManager
{
private:
CentralManagerCppCxShim ^_shim;
DeviceWatcher ^_deviceWatcher;
BluetoothLEAdvertisementWatcher ^_watcher;
EventRegistrationToken _deviceWatcherAdded;
EventRegistrationToken _deviceWatcherRemoved;
EventRegistrationToken _deviceWatcherUpdated;
EventRegistrationToken _watcherReceived;
public:
CentralManagerImpl();
~CentralManagerImpl();
void StartScan();
void StopScan();
}
答案 0 :(得分:0)
经过深入调查后,我得出以下结论:
当卸载DLL(DeviceWatcher
)时,系统无法销毁CentralManagerImpl
C ++类的默认析构函数中的DLL_PROCESS_DETACH
,因为UWP工作线程已被终止系统。我发现唯一可行的解决方案是向我的DLL添加一个新的导出,以便明确地拆除我的C ++类。
我会将此标记为已回答,因为我不相信其他方式。