в моем следующем проекте я хочу реализовать GUI для уже существующего кода в C++. Мой план состоит в том, чтобы обернуть часть C++ в DLL и реализовать GUI в C#. Моя проблема состоит в том, что я не знаю, как реализовать обратный вызов от неуправляемого DLL в manged C# код. Я уже сделал некоторую разработку в C#, но взаимодействие через интерфейс между управляемым и неуправляемым кодом плохо мне знакомо. Кто-либо может дать мне некоторые подсказки или чтение подсказок или простого примера для запуска с? Unfortunatly я ничто не мог найти полезным.
Вам не нужно использовать 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. Доступно приличное учебное пособие .
form _ for
генерирует форму и должен указать все параметры, необходимые для создания search _ path
, поэтому она должна выглядеть следующим образом:
<% form_tag(search_path, :firstname => 'some_text', :lastname => 'some_text', :method => 'get') do %>
или, по крайней мере, примерно так. Тег HTML form
имеет параметр action = '/some/url '
, поэтому необходимо указать все параметры для search _ path
. Но приведенный выше пример не сработает так, как вы ожидали.
Что вы можете сделать?
Создайте пустую форму с действием = '/'
и с помощью js замените ее содержимым текстовых полей ввода перед отправкой.
Создайте другой маршрут, например /search
, который получает параметры из отправки, а затем перенаправляет на правильный путь.
Возможно, есть также несколько лучших способов сделать это;)
-121--4407518-Это анонимный внутренний класс .
Вы определяете три вещи:
запустить
в этом классе В этом примере в потоке Swing должна выполняться некоторая операция ( createAndSunGUI ()
). Невозможно «перейти» в другой поток в середине вызова метода, поэтому вместо этого объект (новый созданный экземпляр) помещается в очередь. Когда поток Swing будет готов, он удалит этот объект из очереди и вызовет метод run
, который, в свою очередь, вызывает createAndSunGUI
. Теперь все происходит правильной нитью.
Функция P/Invoke может обрабатывать упаковку управляемого делегата в указатель функции. Таким образом, если раскрыть API, которые регистрируют функцию обратного вызова из вашей DLL и в C # передать делегат этой функции.
В MSDN приведен пример выполнения этой операции с помощью функции EnumWindows. В этой статье будьте внимательны, чтобы обратить внимание на строку в пункте 4, которая гласит:
Если, однако, функция обратного вызова может вызываться после возврата вызова, управляемый вызывающий абонент должен предпринять шаги для убедиться, что делегат остается не собрано до обратного вызова завершает функцию. Для подробной информации информация о предотвращении мусора коллекция, см. Interop Marshaling с платформой Invoke.
Это означает, что вы должны убедиться, что ваш делегат не собран мусором до тех пор, пока управляемый код не вызовет его, либо сохранив ссылку на него в коде, либо закрепив его.
Посмотрите на это, Marshal.getDelegureForfuncePancePorter ?
См. Marshal.getFunctionPountPointerfordeLegate , который даст вам указатель функции для вызова управляемого (I.E. C # Code) из неуправляемого кода.