Вызов метода C# из кода C++ в WP8

Я заинтересован в вызове метода С# из кода С++ в Windows Phone 8. Я уже научился передавать функцию обратного вызова в код С++ из С# через объявления делегатов в моем коде С++, но я хочу посмотреть, смогу ли я это сделать. любое из следующего:

  • Вызывайте определенные методы непосредственно из кода C++. Это потребует какой-то проверки состава объекта С# из С++, и мне это кажется маловероятным, но я подумал, что все равно спрошу вас всех

  • Инициировать события в коде C#, которые затем могут быть обработаны методами C#.

  • Используйте диспетчер для вызова обратных вызовов C# в основном потоке пользовательского интерфейса, чтобы обратные вызовы могли изменять элементы пользовательского интерфейса.

  • Используйте диспетчер для запуска событий в коде С# (по сути, слияние двух вышеупомянутых точек)

Короче говоря, я ищу столько советов по общению на C++ --> C#, сколько вы, ребята, можете мне подкинуть, я хочу изучить все это. :)


person staticfloat    schedule 21.01.2013    source источник


Ответы (2)


Получив объект в коде C# для реализации интерфейса Windows RT и передав ссылку на этот объект, можно сделать все вышеперечисленное с небольшой настройкой (если я правильно понимаю - не уверен, что именно вы хотите сделать с вашими примерами Dispatcher — вы можете захотеть обернуть Dispatcher на стороне C#).

  1. Создайте библиотеку компонентов среды выполнения Windows.
  2. Определите public interface class в заголовке C++/CX для C# для реализации (C++ для вызова) (например, ICallback).
  3. Определите public ref class в заголовке C++/CX для C++ для реализации (C# для вызова) (например, CppCxClass).
  4. #P2# <блочная цитата>
    ICallback^ globalCallback;
    ...
    void CppCxClass::SetCallback(ICallback ^callback)
    {
        globalCallback = callback;
    }
    
  5. Ссылка на библиотеку WinRT в коде C#.

  6. Код C#: создайте экземпляр CppCxClass с помощью var cppObject = new CppCxClass().
  7. Код C#: создайте класс, реализующий ICallback (например, CSharpCallbackObject).
  8. Код C#: передать экземпляр CSharpCallbackObject на C++. Например. cppObject.SetCallback(new CSharpCallbackObject()).

Теперь вы можете вызывать C# с помощью globalCallback->CallCsharp(L"Hello C#");. Вы должны иметь возможность расширить ICallback и/или CppCxObject для выполнения остальных задач.

person Paul Annetts    schedule 21.01.2013
comment
Здорово! Это ответ почти на все мои вопросы! И последнее: могу ли я использовать какой-нибудь Dispatcher, как у меня в C#, чтобы эти обратные вызовы можно было вызывать внутри основного потока пользовательского интерфейса. - person staticfloat; 21.01.2013
comment
Найдено решение для вопросов диспетчера: stackoverflow.com/questions/10579027/ - person staticfloat; 22.01.2013
comment
Большое спасибо! Я искал такой метод обратного вызова и не мог найти его должным образом описанным где-либо еще. - person Moshe Kravchik; 21.02.2013
comment
Может быть, я новичок в С#, но какое пространство имен необходимо для ICallback? - person RelativeGames; 19.04.2013
comment
Полная реализация + пошаговое руководство по этому решению: developer.nokia.com/Community/Wiki/< /а> - person Berthier Lemieux; 29.04.2013
comment
Я не понимаю. Откуда берется экземпляр класса С#, когда программа запускается на С++? Или как создать экземпляр класса С# в С++? - person Gerold Meisinger; 16.10.2013

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

C++/CX

//.h
[Windows::Foundation::Metadata::WebHostHidden]
public interface class ICallback
{
public:
    virtual void Exec( Platform::String ^Command, Platform::String ^Param);
};
//.cpp
ICallback ^CSCallback = nullptr;
void Direct3DInterop::SetCallback( ICallback ^Callback)
{
    CSCallback = Callback;
}
//...

if (CSCallback != nullptr)
    CSCallback->Exec( "Command", "Param" );

C#

public class CallbackImpl : ICallback
{
    public void Exec(String Command, String Param)
    {
        //Execute some C# code, if you call UI stuff you will need to call this too
        //Deployment.Current.Dispatcher.BeginInvoke(() => { 
        // //Lambda code
        //}
    }
}
//...
CallbackImpl CI = new CallbackImpl();
D3DComponent.SetCallback( CI);
person RelativeGames    schedule 21.04.2013
comment
Это определенно так, потому что такой парень, как я, приходит с той же проблемой, и вы экономите мне кучу времени. Спасибо. - person Nico; 26.06.2013
comment
Было бы здорово, если бы вы могли ответить на соответствующий вопрос SO @ stackoverflow.com/questions/23872394/ - person Arctic; 26.05.2014