2015-02-02 7 views
3

Я вызываю метод C++ из кода C#. Все работает отлично, за исключением возврата нескольких параметров обратно на C#.Как вернуть класс из C++ кода в C#

В моем случае эти параметры: int x, y, width, height;

То, что я хочу сделать, это вернуть класс или структуры из C++ кода C#.

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

C# код код

public class ImageMatch 
{ 
    //method that is used to call pass string parameters and call c++ method 
    [System.Runtime.InteropServices.DllImport("ImageComputingWrapper.dll", CallingConvention = System.Runtime.InteropServices.CallingConvention.Cdecl)] 
    static extern ImageComputingWrapper.ImageParams ComputeImage(string imgPath, string templPath); 

    public GetImgParams(string imgPath, string templPath) 
    { 
     //a class from C++ code 
     ImageComputingWrapper.ImageParams imgParams; 
     //retreive all the data 
     imgParams = ComputeImage(imgPath, templPath); 
    } 
} 

C++

//ImageComputingWrapper.cpp 
extern "C" __declspec(dllexport) ImageComputingWrapper::ImageParams ComputeImage(const char* imgPath, const char* templPath) 
{ 
    computeImage* compImage = new computeImage(imgPath, templPath); 
    ImageComputingWrapper::ImageParams imageParams; 

    imageParams.x = compImage->x; 
    imageParams.y = compImage->y; 
    imageParams.width = compImage->width; 
    imageParams.height = compImage->height; 

    return imageParams; 
} 

//ImageComputingWrapper.h 
//class to return back to c# 
public ref class ImageParams 
{ 
    public: 
     ImageParams(){} 
     int x; 
     int y; 
     int width; 
     int height; 
}; 

Я знаю, что это не возможно вернуть класс из кода C++ на C#, как это в данном примере. Просто понять, что я имел в виду.

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

+0

можно дублировать http://stackoverflow.com/questions/315051/using-a-class -defined-in-ac-dll-in-c-sharp-code – DLeh

+1

Это система :: Рисование :: Прямоугольник. Точка использования C++/CLI заключается в том, чтобы ** не ** использовать [DllImport] в вашей программе на C#. Просто добавьте ссылку на свой проект C++/CLI. Теперь вы увидите только ImageParams, вы уже знаете, как написать настоящий ImageComputingWrapper. –

ответ

3

Вы не можете вернуть класс ref, используя p/invoke. Что вы можете сделать, так это объявить класс ref в вашей сборке C++/CLI и просто использовать это из C#.

Прежде всего вам нужна библиотека классов C++/CLI. Например:

// ClassLibrary1.h 

#pragma once 

using namespace System; 

namespace ClassLibrary1 
{ 
    public ref class Class1 
    { 
    public: 
     int x; 
     int y; 
     int width; 
     int height; 
    public: 
     Class1() : x(42), y(666), width(24), height(13) {} 
    }; 
} 

Вы можете потреблять эту библиотеку классов, как и любой другой управляемой сборки:

using System; 
using ClassLibrary1; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Class1 instance = new Class1(); 
      Console.WriteLine(instance.x); 
      Console.WriteLine(instance.y); 
      Console.WriteLine(instance.width); 
      Console.WriteLine(instance.height); 
     } 
    } 
} 

И это все есть на него.


Вы спрашиваете в комментариях, как передать строковые аргументы в код C++/CLI. Используйте System::String^ на стороне C++/CLI. Это способ C++/CLI ссылаться на тип строки .net. Так что ваш конструктор может стать:

public ref class Class1 
{ 
.... 
public: 
    Class1(System::String^ imgPath, System::String^ tempPath) 
    { 
     .... 
    } 
}; 

На C# стороне вы бы создать экземпляр так:

string imgPath = "..."; 
string tempPath = "..."; 
Class1 instance = new Class1(imgPath, tempPath); 
+0

Спасибо за ваш ответ, я попробую. – Edgar

+0

Да, это действительно хорошее решение +1 @ Давид Хеффернан. Но одна из причин, почему я не выбрал конструктор классов, состоит в том, что я не мог понять, как передать строковые параметры ** imgPath ** и ** templPath ** с C# на C++. Единственный способ, которым я нашел, - использовать dllimport. Я должен сделать этот вопрос больше. – Edgar

+1

В C++/CLI используйте 'System :: String ^', в C# используйте 'string'. Оба они относятся к одному типу, тип строки .net. Я покажу вам обновление. –

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