从 C# 事件触发 C++ 操作
Trigger a C++ action from a C# event
抱歉,如果问题太笼统,但我想知道最好的解决方案是什么。
我有两个项目。主要的是 C++ 并且需要从软件组件接收一些信息。为此,它使用我在 C# 中编写的 .NET dll,并使用 .NET 库从软件组件接收信息。我将编写一个简单的 CLI 项目来获取我的 C# 项目获取的信息。
所以,我的问题是 C# 项目有很多事件订阅,需要从软件组件异步接收信息。所以,我不知道如何在 C++ 中触发一个动作(我的主要项目使用这个 .NET dll 从软件组件中请求信息)来保存当时收集的所有数据。
例如,我在 C# 项目中有这个事件订阅:
private void SubscribeMessages()
{
comm.Comms.Subscribe(new Action<LoadFilterEVENTMessage>(LoadFilterEVENT));
}
private void LoadFilterEVENT(LoadFilterEVENTMessage msg)
{
FilterValue = msg.Filter;
}
所以,我希望这个 LoadFilterEVENT 让 C++ 知道它已经有了过滤器值。有什么提示吗?
先谢谢你:)
这里有一个解决方案:
1- 您的 C# dll 需要加载一个 C++ SubscribeMessages DLL,它将用于使用方法 DispatchEvents
:
通知程序
using System.Runtime.InteropServices;
namespace MyCSharpDLL
{
class PlatformInvokeTest
{
// Import C++ DLL
[DllImport("SubscribeMessages.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void DispatchEvents();
static void LoadFilterEVENT(/*LoadFilterEVENTMessage msg*/)
{
//FilterValue = msg.Filter;
DispatchEvents();
}
/* Methods in DLL being used below */
public static void Main()
{
LoadFilterEVENT();
}
};
}
2-函数DispatchEvents
属于SubscribeMessages.dll
(简单的C++ dll工程)具有释放二进制信号量解锁C++程序的作用:
extern "C" __declspec(dllexport) void DispatchEvents()
{
// Juste open Semaphore
HANDLE ghSemaphore = OpenSemaphore (SEMAPHORE_ALL_ACCESS , TRUE, _T("SemSubscribeMessages"));
if ( NULL == ghSemaphore)
{
MessageBox(NULL,_T("Error when opening semaphore"),_T("Error"),0);
return;
}
// Release semphare in order that CPP program can be notified
ReleaseSemaphore(ghSemaphore, 1, NULL);
}
最后,您的 C++ 程序必须等待 SemSubscribeMessages
信号量才能接收通知。
由于等待阻塞,我将 WaitForSingleObject
函数放在一个单独的 线程 中,这样可以为您的主程序提供更大的灵活性:
#include <windows.h>
#include <iostream>
using namespace std;
// Init value = 0 to block on the first call
#define INITIAL_COUNT 0
// Max value 1 to be a binarySemaphore
#define MAX_SEM_COUNT 1
DWORD WINAPI ListenNewEvent (LPVOID lpParam )
{
DWORD dwWaitResult;
HANDLE ghSemaphore = CreateSemaphore( NULL, INITIAL_COUNT, MAX_SEM_COUNT, _T("SemSubscribeMessages"));
if ( NULL == ghSemaphore) return -1;
while (true)
{
cout<< _T("Wainting for new Events ...")<<endl;
dwWaitResult = WaitForSingleObject( ghSemaphore, INFINITE);
MessageBox(NULL,_T("New Event arrive ..."), _T("Notification"),0);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwThreadId;
HANDLE hListnerThread = CreateThread( NULL, 0, ListenNewEvent, NULL, 0, &dwThreadId);
WaitForSingleObject (hListnerThread, INFINITE);
return 0;
}
结果:
当您 运行 主 CPP 程序时,您会得到:
C#dll发送通知后,您将得到:
如果您也需要共享数据(除了事件之外),您可以在通知后添加一个 "shared memory" 层...希望这对您有所帮助
抱歉,如果问题太笼统,但我想知道最好的解决方案是什么。
我有两个项目。主要的是 C++ 并且需要从软件组件接收一些信息。为此,它使用我在 C# 中编写的 .NET dll,并使用 .NET 库从软件组件接收信息。我将编写一个简单的 CLI 项目来获取我的 C# 项目获取的信息。
所以,我的问题是 C# 项目有很多事件订阅,需要从软件组件异步接收信息。所以,我不知道如何在 C++ 中触发一个动作(我的主要项目使用这个 .NET dll 从软件组件中请求信息)来保存当时收集的所有数据。
例如,我在 C# 项目中有这个事件订阅:
private void SubscribeMessages()
{
comm.Comms.Subscribe(new Action<LoadFilterEVENTMessage>(LoadFilterEVENT));
}
private void LoadFilterEVENT(LoadFilterEVENTMessage msg)
{
FilterValue = msg.Filter;
}
所以,我希望这个 LoadFilterEVENT 让 C++ 知道它已经有了过滤器值。有什么提示吗?
先谢谢你:)
这里有一个解决方案:
1- 您的 C# dll 需要加载一个 C++ SubscribeMessages DLL,它将用于使用方法 DispatchEvents
:
using System.Runtime.InteropServices;
namespace MyCSharpDLL
{
class PlatformInvokeTest
{
// Import C++ DLL
[DllImport("SubscribeMessages.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void DispatchEvents();
static void LoadFilterEVENT(/*LoadFilterEVENTMessage msg*/)
{
//FilterValue = msg.Filter;
DispatchEvents();
}
/* Methods in DLL being used below */
public static void Main()
{
LoadFilterEVENT();
}
};
}
2-函数DispatchEvents
属于SubscribeMessages.dll
(简单的C++ dll工程)具有释放二进制信号量解锁C++程序的作用:
extern "C" __declspec(dllexport) void DispatchEvents()
{
// Juste open Semaphore
HANDLE ghSemaphore = OpenSemaphore (SEMAPHORE_ALL_ACCESS , TRUE, _T("SemSubscribeMessages"));
if ( NULL == ghSemaphore)
{
MessageBox(NULL,_T("Error when opening semaphore"),_T("Error"),0);
return;
}
// Release semphare in order that CPP program can be notified
ReleaseSemaphore(ghSemaphore, 1, NULL);
}
最后,您的 C++ 程序必须等待 SemSubscribeMessages
信号量才能接收通知。
由于等待阻塞,我将 WaitForSingleObject
函数放在一个单独的 线程 中,这样可以为您的主程序提供更大的灵活性:
#include <windows.h>
#include <iostream>
using namespace std;
// Init value = 0 to block on the first call
#define INITIAL_COUNT 0
// Max value 1 to be a binarySemaphore
#define MAX_SEM_COUNT 1
DWORD WINAPI ListenNewEvent (LPVOID lpParam )
{
DWORD dwWaitResult;
HANDLE ghSemaphore = CreateSemaphore( NULL, INITIAL_COUNT, MAX_SEM_COUNT, _T("SemSubscribeMessages"));
if ( NULL == ghSemaphore) return -1;
while (true)
{
cout<< _T("Wainting for new Events ...")<<endl;
dwWaitResult = WaitForSingleObject( ghSemaphore, INFINITE);
MessageBox(NULL,_T("New Event arrive ..."), _T("Notification"),0);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwThreadId;
HANDLE hListnerThread = CreateThread( NULL, 0, ListenNewEvent, NULL, 0, &dwThreadId);
WaitForSingleObject (hListnerThread, INFINITE);
return 0;
}
结果:
当您 运行 主 CPP 程序时,您会得到:
C#dll发送通知后,您将得到:
如果您也需要共享数据(除了事件之外),您可以在通知后添加一个 "shared memory" 层...希望这对您有所帮助