Оболочка C++ clr/cli для проблемы обратного вызова C#C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Оболочка C++ clr/cli для проблемы обратного вызова C#

Сообщение Anonymous »

Я работаю над созданием библиотеки C#, позволяющей использовать некоторые функциональные возможности .net (framework 4.7.1) и API, работающие в устаревшем приложении MFC (теперь работающем в VS2017).
В моих первоначальных тестах все работало нормально, когда я ждал в коде C# ответов API.
Я хочу расширить эту тему и создать обратный вызов/событие, а не ждать ответ.
Вот код:
Код C#

Код: Выделить всё

using System;
using System.Threading.Tasks;

namespace Async_Event
{
public class AsyncProcessor
{
public event EventHandler OnResultReady;

public async Task ProcessAsync()
{
// Simulate async work
await Task.Delay(1000);
string result = "Async Result";

// Raise the event
OnResultReady?.Invoke(this, result);

return result;
}
}

}
оболочка C++

Код: Выделить всё

///// CS_APIWrapper.h
#pragma once

using namespace System;
using namespace System::Threading::Tasks;
using namespace Async_Event;

namespace CSAPIWrapper
{
public ref class AsyncProcessorWrapper
{
public:
delegate void ResultReadyHandler(String^ result);
event ResultReadyHandler^ OnResultReady;

AsyncProcessorWrapper();
void ProcessAsync();

private:
AsyncProcessor^ processor;

Task^ RunProcessAsync();
void OnResultReadyHandler(Object^ sender, String^ result);
};
}

///// CS_APIWrapper.cpp
#include "pch.h"
#include "CS_APIWrapper.h"

using namespace System;
using namespace CSAPIWrapper;

AsyncProcessorWrapper::AsyncProcessorWrapper()
{
processor = gcnew AsyncProcessor();
processor->OnResultReady += gcnew EventHandler(this, &AsyncProcessorWrapper::OnResultReadyHandler);
}

void AsyncProcessorWrapper::ProcessAsync()
{
//  Task::Run(gcnew Func(processor, &AsyncProcessor::ProcessAsync));
Task::Run(gcnew Func(this, &AsyncProcessorWrapper::RunProcessAsync));
}

Task^ AsyncProcessorWrapper::RunProcessAsync()
{
return processor->ProcessAsync();
}

void AsyncProcessorWrapper::OnResultReadyHandler(Object^ sender, String^ result)
{
OnResultReady(result);
}
и родной вызывающий объект

Код: Выделить всё

///// CS_APICaller.h

#pragma once

#include 
#include 
using namespace System;
#include "CS_APIWrapper.h"

class NativeAsyncProcessor
{
public:
NativeAsyncProcessor();
~NativeAsyncProcessor();

void ProcessAsync();
void SetResultCallback(void(*callback)(const std::string&));

private:
gcroot  processorWrapper;
static void(*resultCallback)(const std::string&);

void OnResultReady(System::String^ result);
};

///// CS_APICaller.cpp

#include "CS_APICaller.h"
#include "CS_APIWrapper.h"
#include 
using namespace CSAPIWrapper;

void(*NativeAsyncProcessor::resultCallback)(const std::string&) = nullptr;

NativeAsyncProcessor::NativeAsyncProcessor()
{
processorWrapper = gcnew AsyncProcessorWrapper();
processorWrapper->OnResultReady += gcnew AsyncProcessorWrapper::ResultReadyHandler(this, &NativeAsyncProcessor::OnResultReady);
}

NativeAsyncProcessor::~NativeAsyncProcessor()
{
delete processorWrapper;
}

void NativeAsyncProcessor::ProcessAsync()
{
processorWrapper->ProcessAsync();
}

void NativeAsyncProcessor::SetResultCallback(void(*callback)(const std::string&))
{
resultCallback = callback;
}

void NativeAsyncProcessor::OnResultReady(System::String^ result)
{
if (resultCallback)
{
std::string unmanaged = msclr::interop::marshal_as(result);
resultCallback(unmanaged);
}
}
Эта строка выдает ошибку:

Код: Выделить всё

processorWrapper-\>OnResultReady += gcnew AsyncProcessorWrapper::ResultReadyHandler(this, &NativeAsyncProcessor::OnResultReady);

NativeAsyncProcessor::OnResultReady
Invalid delegate initializer – function is not a member of a managed class
Этот класс не является управляемым, но мне нужен обратный вызов в неуправляемом коде.
Что мне не хватает? Как заставить обратный вызов работать?
Существует так много информации о том, как пойти другим путем (C# вызывает библиотеки C++), но я не могу найти много информации о том, как сделать это другим способом. в обход.

Подробнее здесь: https://stackoverflow.com/questions/792 ... ck-problem
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»