Интерфейс обратного вызова реализации с практическими рекомендациями от неуправляемого DLL до приложения .NET?

в моем следующем проекте я хочу реализовать GUI для уже существующего кода в C++. Мой план состоит в том, чтобы обернуть часть C++ в DLL и реализовать GUI в C#. Моя проблема состоит в том, что я не знаю, как реализовать обратный вызов от неуправляемого DLL в manged C# код. Я уже сделал некоторую разработку в C#, но взаимодействие через интерфейс между управляемым и неуправляемым кодом плохо мне знакомо. Кто-либо может дать мне некоторые подсказки или чтение подсказок или простого примера для запуска с? Unfortunatly я ничто не мог найти полезным.

23
задан chrmue 30 January 2010 в 12:46
поделиться

4 ответа

Вам не нужно использовать Marshal.getFunctionPountPointerFordelegate (), Marshaller P / Invoke делает его автоматически. Вам нужно будет объявить делегат на стороне C #, сигнатура которой совместима с объявлением указателя функции на стороне C ++. Например:

using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

class UnManagedInterop {
  private delegate int Callback(string text);
  private Callback mInstance;   // Ensure it doesn't get garbage collected

  public UnManagedInterop() {
    mInstance = new Callback(Handler);
    SetCallback(mInstance);
  }
  public void Test() {
    TestCallback();
  }

  private int Handler(string text) {
    // Do something...
    Console.WriteLine(text);
    return 42;
  }
  [DllImport("cpptemp1.dll")]
  private static extern void SetCallback(Callback fn);
  [DllImport("cpptemp1.dll")]
  private static extern void TestCallback();
}

и соответствующий код C ++, используемый для создания неуправляемой DLL:

#include "stdafx.h"

typedef int (__stdcall * Callback)(const char* text);

Callback Handler = 0;

extern "C" __declspec(dllexport)
void __stdcall SetCallback(Callback handler) {
  Handler = handler;
}

extern "C" __declspec(dllexport)
void __stdcall TestCallback() {
  int retval = Handler("hello world");
}

, этого достаточно, чтобы начать с ним. Есть миллион подробностей, которые могут попасть в беду, вы обязаны бежать в некоторых из них. Гораздо более продуктивный способ получить этот вид кода, пишет обертку на языке C ++ / CLI. Это также позволяет обернуть класс C ++, то, что вы не можете сделать с P / Invoke. Доступно приличное учебное пособие .

50
ответ дан 29 November 2019 в 01:18
поделиться

form _ for генерирует форму и должен указать все параметры, необходимые для создания search _ path , поэтому она должна выглядеть следующим образом:

<% form_tag(search_path, :firstname => 'some_text', :lastname => 'some_text', :method => 'get') do %>

или, по крайней мере, примерно так. Тег HTML form имеет параметр action = '/some/url ', поэтому необходимо указать все параметры для search _ path . Но приведенный выше пример не сработает так, как вы ожидали.

Что вы можете сделать?

  1. Создайте пустую форму с действием = '/' и с помощью js замените ее содержимым текстовых полей ввода перед отправкой.

  2. Создайте другой маршрут, например /search , который получает параметры из отправки, а затем перенаправляет на правильный путь.

Возможно, есть также несколько лучших способов сделать это;)

-121--4407518-

Это анонимный внутренний класс .

Вы определяете три вещи:

  • Новый класс
  • Метод, называемый запустить в этом классе
  • Новый экземпляр этого класса

В этом примере в потоке Swing должна выполняться некоторая операция ( createAndSunGUI () ). Невозможно «перейти» в другой поток в середине вызова метода, поэтому вместо этого объект (новый созданный экземпляр) помещается в очередь. Когда поток Swing будет готов, он удалит этот объект из очереди и вызовет метод run , который, в свою очередь, вызывает createAndSunGUI . Теперь все происходит правильной нитью.

-121--3823345-

Функция P/Invoke может обрабатывать упаковку управляемого делегата в указатель функции. Таким образом, если раскрыть API, которые регистрируют функцию обратного вызова из вашей DLL и в C # передать делегат этой функции.

В MSDN приведен пример выполнения этой операции с помощью функции EnumWindows. В этой статье будьте внимательны, чтобы обратить внимание на строку в пункте 4, которая гласит:

Если, однако, функция обратного вызова может вызываться после возврата вызова, управляемый вызывающий абонент должен предпринять шаги для убедиться, что делегат остается не собрано до обратного вызова завершает функцию. Для подробной информации информация о предотвращении мусора коллекция, см. Interop Marshaling с платформой Invoke.

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

6
ответ дан 29 November 2019 в 01:18
поделиться

Посмотрите на это, Marshal.getDelegureForfuncePancePorter ?

0
ответ дан 29 November 2019 в 01:18
поделиться

См. Marshal.getFunctionPountPointerfordeLegate , который даст вам указатель функции для вызова управляемого (I.E. C # Code) из неуправляемого кода.

1
ответ дан 29 November 2019 в 01:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: