2015-05-29 3 views
0

Мой проект требует, чтобы я использовал C# для предоставления пользовательского интерфейса C++. Одна из функций C++, которую я вызываю, выполняет кучу работы и предоставляет периодические обновления прогресса через другой «объект». Вот пример того, что я имею в виду.Вызов функции C# из функции C++/CLI

C++

class AppDelegate : public ProgressDelegate 
    { 
    void AppDelegate::UpdateStatusText(const char* text) 
     { 
     // Go() will end up calling me at some point. 
     OutputDebugString(text); 
     } 
    void AppDelegate::ShowMessage(const char* text) 
     { 
     // Go() will end up calling me at some point. 
     OutputDebugString(text); 
     } 
    }; 

int CppWrapper::Go() 
    { 
    return cppInstance->Go() 
    } 

CSharp

void UpdateStatusText(String text) 
    { 
    //update UI 
    } 
void ShowMessage(String text) 
    { 
    //update UI 
    } 

То, что я хочу сделать, это принять updateStatusText и ShowMessage и передать текст к C#, чтобы обновить пользовательский интерфейс. Мой вопрос в том, как я могу предоставить соответствующие методы C#, чтобы их можно было вызвать с помощью моего кода на C++? Обратите внимание, что изменение Go не является для меня вариантом.

ответ

1

Может быть, этот пример может помочь вам:

Написать Managed DLL

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

Запустите Microsoft Visual Studio .NET или Microsoft Visual Studio 2005. В меню «Файл» выберите «Создать», а затем «Проект». Откроется диалоговое окно «Новый проект». В разделе «Типы проектов» выберите «Проекты Visual C#».

Примечание. В Visual Studio 2005 щелкните Visual C# в разделе Типы проектов. В разделе «Шаблоны» выберите «Библиотека классов». В текстовом поле Имя введите sManagedDLL и нажмите кнопку ОК. Откройте файл Class1.cs в виде кода. Чтобы объявить открытый интерфейс, который имеет метод сложения двух чисел, добавьте следующий код в файл Class1.cs:

// Interface declaration. 
public interface ICalculator 
{ 
    int Add(int Number1, int Number2); 
}; 

Для реализации этого общего интерфейса в классе, добавьте следующий код в Class1. CS-файл:

// Interface implementation. 
public class ManagedClass:ICalculator 
{ 
    public int Add(int Number1,int Number2) 
     { 
      return Number1+Number2; 
     } 
} 

Зарегистрируйте Managed DLL для использования с COM или Native C++ Чтобы использовать управляемый DLL с COM или родной C++, вы должны зарегистрировать информацию сборки вашей DLL в системном реестре Windows, ,Чтобы сделать это, выполните следующие действия:

Вызов Управляется DLL из Native C++ код

// Import the type library. 
#import "..\ManagedDLL\bin\Debug\ManagedDLL.tlb" raw_interfaces_only 

Изменить путь к библиотеке типов, если путь на вашем компьютере отличается от этого пути. Чтобы объявить пространство имен для использования, добавьте следующий код в файл CPPClient.cpp:

using namespace ManagedDLL; 

Полный листинг кода

//Managed DLL 
    // Class1.cs 
    // A simple managed DLL that contains a method to add two numbers. 
    using System; 

    namespace ManagedDLL 
    { 
    // Interface declaration. 
     public interface ICalculator 
     { 
      int Add(int Number1, int Number2); 
     }; 

     // Interface implementation. 
    public class ManagedClass:ICalculator 
    { 
     public int Add(int Number1,int Number2) 
       { 
        return Number1+Number2; 
       } 
    } 
    } 


    //C++ Client 
    // CPPClient.cpp: Defines the entry point for the console application. 
    // C++ client that calls a managed DLL. 

    #include "stdafx.h" 
    #include "tchar.h" 
    // Import the type library. 

    #import "..\ManagedDLL\bin\Debug\ManagedDLL.tlb" raw_interfaces_only 
    using namespace ManagedDLL; 
    int _tmain(int argc, _TCHAR* argv[]) 
    { 
     // Initialize COM. 
     HRESULT hr = CoInitialize(NULL); 

     // Create the interface pointer. 
     ICalculatorPtr pICalc(__uuidof(ManagedClass)); 

     long lResult = 0; 

     // Call the Add method. 
     pICalc->Add(5, 10, &lResult); 

     wprintf(L"The result is %d\n", lResult); 


     // Uninitialize COM. 
     CoUninitialize(); 
     return 0; 
    } 

Ссылка: How to call a managed DLL from native Visual C++ code in Visual Studio.NET or in Visual Studio 2005

+0

Зачем нужен класс интерфейса? Можно ли получить доступ к обычным классам? – Mosi

0

Вам нужно будет создать соответствующий код C# в сборке, а затем ссылаться на эту сборку в проекте C++ CLI. Внутри вашей оболочки C++ CLI вы совершаете вызовы функций, открытых через эту сборку C#, также вы будете делать вызовы в собственный код на C++.

Проект C++ CLI может содержать собственный код на C++, просто убедитесь, что CLR-переключатель не включен для собственных файлов. Итак, у вас будет 3 проекта:

  1. Проект C# для GUI, который будет ссылаться на главный. Также ссылается на сборку, используемую для вызова функций C#, которые вызывается через C++ interop.
  2. C# сборка, которая предоставляет определенные управляемые функции (таким образом вызываемые из C++ CLI)
  3. Проект C++ CLI, который будет обертываться, а также содержать собственный код.
1

В качестве альтернативы, то, что я использовал (до того, как я переключился на использование метода P/Invoke для вызова с C# на C++), должно было быть 3 proj ects (как сказал StraightLine), но у меня были бы C#, Managed C++ и Native C++, а Managed C++ - мой мост/прокси, чтобы поговорить между ними (Native C++ и C#). Это облегчило работу на моей родной стороне C++. Одно из предостережений заключается в том, что некоторые из STL (в основном контейнеров) не поддерживаются управляемыми или иногда, поведение std :: string (Managed C++ version) приведет к исключениям при использовании в Native C++ std :: string, поэтому обратите внимание на то, что Библиотеки STL поддерживают Managed C++.

Кроме того, как сказал StraightLine, мостовой код (в моем случае Manaaged C++) должен иметь оболочку, которая будет маршалировать от управляемого к коренному и наоборот (т. Е. Ваш «const char *» в System.String , если ваш символ 8 бит и т. д.)

+0

Как вы звонили из C++ в C# внутри своей установки? Вы должны создать проект C# для исполняемого файла, а не для библиотеки. Как же вы ссылаетесь на него из других мест? OP говорит, что его GUI находится на C#, поэтому он должен построить свой код C# в исполняемом файле –

Смежные вопросы