Member 14686752 Ответов: 1

Как получить ответ от сервера


Клиент находится на языке c#, а сервер-на языке C++.
Клиент выглядит следующим образом:
client.cs
namespace clinetspace
{
      public class client
      {
           [DllImport("Server.dll")]
           static public extern void CallServer(IntPtr obj, int a);
           [DllImport("Server.dll")]
           static public extern IntPtr CreateServer();

           IntPtr obj;
           public static void main()
           {
                 obj = CreateServer();
                 CallServer(obj, 1);
           }
      }
}

у клиента есть и другие методы, которые я вызываю так же, как метод CallServer (), и все они работают нормально.
а сервер выглядит следующим образом:
Server.h
extern "C" __declspec(dllexport) MyServer* CreateServer();
extern "C" __declspec(dllexport) void CallServer(MyServer* server, int i);

Server.cpp

#include "Server.h"
#include "MyServer.h"
public void CreateServer()
{
     return new MyServer();
}

public void CallServer(MyServer* server, int i)
{
       server->StartServer(i);
}

внутренне StartServer() выполняет другие операции. Все операции и методы вызова c++ из c# работают нормально.
Теперь мой вопрос заключается в том, если сервер выдает какую-то ошибку, как я могу передать ошибку клиенту, и клиент действует соответственно и показывает правильное сообщение об ошибке пользователю.
Ошибка-это как структура:
structure Error
{
    int errorCode;
    string errorMessage;
}


Что я уже пробовал:

Я не уверен, что все, что я пытаюсь сделать, правильно или нет.
Я пытаюсь решить эту проблему с помощью делегатов в c#. код выглядит следующим образом:
 Modify client.cs as follows:

 [UnmanagedFunctionPointer(CallingConvention.StdCall)]
 delegate void ProgressCallback(int key, string value);
 [DllImport("Server.dll")]
 public static extern void DoWork([MarshalAs(UnmanagedType.FunctionPtr)] ProgressCallback callbackPointer);

public static void ServerResponse(int key, string value)
{
     Console.WriteLine("Errorcode is"+ key + "Error Message is"+value);
}
modify the main method as:
ProgressCallBack pcb = new ProgressCallBack(ServerResponse);
DoWork(ServerResponse);

и измените сервер следующим образом:
Server.h
extern "C" typedef void (__stdcall * ProgressCallback)(int, char*);
extern "C" __declspec(dllexport) void DoWork(ProgressCallback progressCallback);

и еще Server.cpp
void DoWork(ProgressCallback progressCallback)
{
    if (progressCallback)
    {
        progressCallback(0, "Error Message");
    }
}

Этот параметр метода имеет ссылку ProgressCallback, которая поступает от клиента. Есть ли какой-нибудь способ сохранить эту ссылку в любой глобальной переменной, чтобы она была доступна везде на сервере и когда сервер захочет отправить ошибку клиенту, он будет использовать эту переменную.

Gerry Schmitz

Сервер возвращает "коды ошибок" как часть цикла запрос-ответ; он не выполняет специальные обратные вызовы.

Member 14686752

Этот код ошибки определен мной. Если что-то не удается на сервере, я назначаю коды ошибок и соответствующее сообщение об ошибке. Теперь я хочу как-то передать эту информацию клиенту.

1 Ответов

Рейтинг:
0

Shao Voon Wong

Клиент C# может выполнять опрос. Хотя опрос легко сделать, он неэффективен и является пустой тратой циклов процессора. Сервер C++ может создавать события(CreateEvent[^]) и сигнализировать событию обрабатывать все, что есть данные, которые должны быть получены. Клиент C# создаст объект Класс AutoResetEvent (System.Продевать Нитку) | Майкрософт Документы[^] передавая false для initialState конструктору. Клиент c# будем ждать вызов метода waitone(); который представляет собой блокирующий вызов или ОП предпочитает называть Метод WaitAny[^] который имеет перегруженный метод тайм-аута.


Member 14686752

Спасибо за ответ. Я новичок в этом, любое небольшое примерное приложение или любая ссылка на примерное приложение будут более полезны.

Shao Voon Wong

Привет, я поместил образец кода на GitHub.

https://github.com/shaovoon/CSharpCppDllComm

Нажмите кнопку "Создать сервер", затем нажмите кнопку "Отправить Cpp Msg", чтобы имитировать сигнал от Cpp-сервера, чтобы сообщить C#, чтобы получить сообщение.

Member 14686752

Спасибо за этот пример приложения. Если ваша библиотека dll c++ имеет другие методы и эти методы имеют некоторые сообщения об ошибках, которые вам нужно отправить клиенту, как это сделать в вашем примере приложения.

Shao Voon Wong

Просто добавьте 2 метода, HasError() и GetLastError(). Держите взаимодействие простым.