gpt4 book ai didi

c# - C++ 应用程序通知 C# 应用程序

转载 作者:搜寻专家 更新时间:2023-10-31 02:05:30 24 4
gpt4 key购买 nike

我目前有一个 C++ 应用程序和一个 C# 应用程序,我希望我的 C++ 应用程序通知 C# 应用程序发生了某些事情(例如事件),我现在正在做的是使用共享内存,例如:

C++:
CreateFileMappingW(L"MySharedMemory");

C#:
MemoryMappedFile.OpenExisting("MySharedMemory")

所以 C++ 应用程序在共享内存中写入一个标志,然后 C# 应用程序读取这个标志并知道发生了什么,但这是一个坏主意,因为 C# 应用程序必须不断检查标志,所以有更好的主意吗?

最佳答案

好的,抱歉,如果它有点乱或写得不好,这是我前段时间编辑的一些遗留物,是的,我知道,我没有遵循命名标准,我感到羞耻 ^^

我会让你打扫干净,拿走你需要的东西。只是为了上下文,在我的例子中,C++ 应用程序正在创建命名管道,并且每次写入“'代码的大小'-'代码''可能是一些废话'”,其中代码是我需要几乎实时检索的字母数字代码.

这是处理大部分命名管道处理的类:

using System;
using System.Collections.Generic;
using Microsoft.Win32.SafeHandles;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;

namespace NamedPipe
{
public class NamedPipeServer
{
[DllImport("kernel32.dll", SetLastError = true)]
public static extern SafeFileHandle CreateNamedPipe(
String sPipeName,
uint dwOpenMode,
uint dwPipeMode,
uint nMaxInstances,
uint nOutBufferSize,
uint nInBufferSize,
uint nDefaultTimeOut,
IntPtr lpSecurityAttributes);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern int ConnectNamedPipe(SafeFileHandle hNamedPipe, IntPtr lpOverlapped);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern int DisconnectNamedPipe(SafeFileHandle hNamedPipe);
public const uint DUPLEX = (0x00000003);
public const uint FILE_FLAG_OVERLAPPED = (0x40000000);
public List<string> m_ReceivedValues = new List<string>();

public class Client
{
public SafeFileHandle handle;
public FileStream stream;
}

public const int BUFFER_SIZE = 100;
public Client m_clientse = null;
public string m_sPipeName;
Thread m_listenThread;
SafeFileHandle m_clientHandle;

public NamedPipeServer(string PName)
{
m_sPipeName = PName;
}

public void Start()
{
m_listenThread = new Thread(new ThreadStart(ListenForClients));
m_listenThread.Start();
}
private void ListenForClients()
{
while (true)
{
m_clientHandle = CreateNamedPipe(m_sPipeName, DUPLEX | FILE_FLAG_OVERLAPPED, 0, 255, BUFFER_SIZE, BUFFER_SIZE, 0, IntPtr.Zero);
if (m_clientHandle.IsInvalid)
return;

int success = ConnectNamedPipe(m_clientHandle, IntPtr.Zero);
if (success == 0)
return;

m_clientse = new Client();
m_clientse.handle = m_clientHandle;
m_clientse.stream = new FileStream(m_clientse.handle, FileAccess.ReadWrite, BUFFER_SIZE, true);

Thread readThread = new Thread(new ThreadStart(Read));
readThread.Start();
}
}
private void Read()
{
byte[] buffer = null;
ASCIIEncoding encoder = new ASCIIEncoding();

while (true)
{
int bytesRead = 0;
try
{
buffer = new byte[BUFFER_SIZE];
bytesRead = m_clientse.stream.Read(buffer, 0, BUFFER_SIZE);
}
catch
{
//read error has occurred
break;
}

//client has disconnected
if (bytesRead == 0)
break;

int ReadLength = 0;
for (int i = 0; i < BUFFER_SIZE; i++)
{
if (buffer[i].ToString("x2") != "cc")
{
ReadLength++;
}
else
break;
}
if (ReadLength > 0)
{
byte[] Rc = new byte[ReadLength];
Buffer.BlockCopy(buffer, 0, Rc, 0, ReadLength);
string sReadValue = encoder.GetString(Rc, 0, ReadLength);
string[] codeInfo = sReadValue.Split('-');
if (codeInfo.Length == 2)
{
string sSize = codeInfo[0];
string sCode = codeInfo[1];
string sFinalValue = sCode;
int nSize = Int32.Parse(sSize);
if (sCode.Length >= nSize)
{
sFinalValue = sCode.Substring(0, nSize);
}
m_ReceivedValues.Add(sFinalValue);
Console.WriteLine($"C# App: Received value : {sFinalValue}");
buffer.Initialize();
}
else
{
Console.WriteLine("C# App: Received value in named pipe is badly formatted (we expect 'size-code')");
}
}
}
m_clientse.stream.Close();
m_clientse.handle.Close();
}

public void StopServer()
{
DisconnectNamedPipe(m_clientHandle);
m_listenThread.Abort();
}
}
}

然后我就这样使用了:

NamedPipeServer m_pPipeServer = null;
[...]
m_pPipeServer = new NamedPipeServer(@"\\.\pipe\myPipe");
m_pPipeServer.Start();
[...]
if (m_pPipeServer != null)
{
if (m_pPipeServer.m_ReceivedValues.Count > 0)
{
string sLastReceivedValue = m_pPipeServer.m_ReceivedValues.ElementAt(0);
[...]
m_pPipeServer.m_ReceivedValues.RemoveAt(0);
}
}
[...]
m_pPipeServer.StopServer();

希望对您有所帮助;)

编辑(如果您需要 C++ 部分,我刚找到它):

HANDLE  m_hDemoPipe;
m_hDemoPipe = CreateFile("\\\\.\\pipe\\myPipe", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

[...]

char buf[100];
CString sValue;
USES_CONVERSION;
sValue.Format(_T("%ld-%s"), sMsg.GetLength(), sMsg);
CStringA sValueAnsi = T2A(sValue);
for (int i = 0; i < sValueAnsi.GetLength(); ++i)
{
buf[i] = static_cast<char>( sValueAnsi.GetAt(i) );
}
DWORD cbWritten;
DWORD dwBytesToWrite = (DWORD)strlen(buf);
WriteFile(m_hDemoPipe, buf, dwBytesToWrite, &cbWritten, NULL);

[...]

CloseHandle(m_hDemoPipe);

关于c# - C++ 应用程序通知 C# 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51891825/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com