C++;回调到C#:类型为'的未处理异常;System.ExecutionEngineeException';发生在未知模块中 我的项目中有.NET核心3.1 C·WPF应用程序和非托管C++ DLL。从C++ DLL中,我必须实现回调。下面的代码运行约30秒。之后,我在“_observer(message);”行上得到以下错误消息:未知模块中发生类型为“System.ExecutionEngineeException”的未处理异常
谢谢你的提示 C++dll:C++;回调到C#:类型为'的未处理异常;System.ExecutionEngineeException';发生在未知模块中 我的项目中有.NET核心3.1 C·WPF应用程序和非托管C++ DLL。从C++ DLL中,我必须实现回调。下面的代码运行约30秒。之后,我在“_observer(message);”行上得到以下错误消息:未知模块中发生类型为“System.ExecutionEngineeException”的未处理异常,c#,c++,C#,C++,谢谢你的提示 C++dll: #include <windows.h> extern "C" __declspec(dllexport) void __cdecl TestDll_AddObserver(void (__cdecl *observer)(const char* message)); void (__cdecl *_observer)(const char* message); void __cdecl TestDll_AddObserver(
#include <windows.h>
extern "C" __declspec(dllexport) void __cdecl TestDll_AddObserver(void (__cdecl *observer)(const char* message));
void (__cdecl *_observer)(const char* message);
void __cdecl TestDll_AddObserver(void (__cdecl *observer)(const char* message))
{
_observer = observer;
}
DWORD WINAPI MainThread(LPVOID data)
{
char message[] = "Hello world!\n";
for (;;)
{
if (_observer != nullptr)
{
_observer(message); // Line the exception occurs
}
Sleep(2000);
}
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
CreateThread(NULL, 0, MainThread, NULL, 0, NULL);
}
return TRUE;
}
#包括
外部“C”uuu declspec(dllexport)void uuu cdecl TestDll_uaddobserver(void(uuu cdecl*observer)(const char*message));
无效(uuu cdecl*u observer)(常量字符*消息);
void uu cdecl TestDll u AddObserver(void(uu cdecl*observer)(const char*message))
{
_观察者=观察者;
}
DWORD WINAPI主线程(LPVOID数据)
{
char message[]=“你好,世界!\n”;
对于(;;)
{
如果(_observer!=nullptr)
{
_观察者(消息);//发生异常的行
}
睡眠(2000年);
}
}
BOOL WINAPI DllMain(HINSTANCE hinstDLL、DWORD fdreason、LPVOID lpReserved)
{
如果(fdareason==DLL\u进程\u附加)
{
CreateThread(NULL,0,MainThread,NULL,0,NULL);
}
返回TRUE;
}
C#应用程序:
使用系统;
使用System.Runtime.InteropServices;
使用System.Windows;
名称空间WpfApp
{
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口
{
[非托管函数指针(CallingConvention.Cdecl)]
公共委托void MessageDelegate(IntPtr messagePointer);
[DllImport(“TestDll.dll”,CallingConvention=CallingConvention.Cdecl)]
私有静态外部void TestDll_AddObserver(MessageDelegate messageHandler);
公共主窗口()
{
初始化组件();
}
public void OnLoad(对象发送方,RoutedEventArgs e)
{
TestDll_AddObserver(OnMessage);
}
私有静态void OnMessage(IntPtr messagePointer)
{
if(messagePointer!=null)
{
string message=Marshal.PtrToStringAnsi(messagePointer);
系统.诊断.调试.写入(消息);
}
}
}
TestDll\u AddObserver(OnMessage);
是TestDll\u AddObserver(new MessageDelegate(OnMessage))的糖;
--需要保持MessageDelegate
实例处于活动状态(例如,在字段中)只要C++代码可以尝试调用它,就可以看到,GC会在某个时候出现并收集它,然后当C++方尝试调用时,它就会崩溃。it@canton7您确定在该函数之外没有读取权限的字段实际上不会被优化掉吗?@Charlieface是的。字段不能被优化掉,尤其是因为它们对反射总是可见的(因此序列化等等)。在这种情况下,它也会引起行为的可观察变化,非常感谢您的回答!正是这个问题。现在它工作得很好。
using System;
using System.Runtime.InteropServices;
using System.Windows;
namespace WpfApp
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void MessageDelegate(IntPtr messagePointer);
[DllImport("TestDll.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void TestDll_AddObserver(MessageDelegate messageHandler);
public MainWindow()
{
InitializeComponent();
}
public void OnLoad(object sender, RoutedEventArgs e)
{
TestDll_AddObserver(OnMessage);
}
private static void OnMessage(IntPtr messagePointer)
{
if (messagePointer != null)
{
string message = Marshal.PtrToStringAnsi(messagePointer);
System.Diagnostics.Debug.Write(message);
}
}
}