【问题标题】:How to return class from c++ code to c#如何将类从 C++ 代码返回到 C#
【发布时间】:2015-02-02 20:21:16
【问题描述】:

我正在从 C# 代码调用 C++ 方法。除了将多个参数返回到 C# 之外,一切正常。

在我的例子中,这些参数是:int x, y, width, height;

我想要做的是将一个类或结构从 c++ 代码返回到 c#。

我提供了一个例子,这样我的想法就会更加清楚。我知道一种方法是使用 Marshal 类,也许是唯一的方法。

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++ 代码(指针)可能有问题。

【问题讨论】:

  • 这是一个 System::Drawing::Rectangle。使用 C++/CLI 的目的是不必在你的 C# 程序中使用 [DllImport]。只需添加对 C++/CLI 项目的引用。你现在只会看到 ImageParams,你已经知道如何写一个真正的 ImageComputingWrapper

标签: c# c++-cli dllimport


【解决方案1】:

您不能使用 p/invoke 返回 ref 类。您可以做的是在您的 C++/CLI 程序集中声明一个 ref 类,然后简单地从 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);
        }
    }
}

仅此而已。


您在 cmets 中询问如何将字符串参数传递给 C++/CLI 代码。在 C++/CLI 端使用 System::String^。这是引用 .net 字符串类型的 C++/CLI 方式。所以你的构造函数可能变成:

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

在 C# 端,您可以这样创建实例:

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

【讨论】:

  • 谢谢你的回答,我试试看。
  • 是的,这是非常好的解决方案 +1 @David Heffernan。但是我没有选择类构造函数的一个原因是我不知道如何将字符串参数 imgPathtemplPath 从 c# 传递到 c++。我发现的唯一方法是使用 dllimport。我应该更多地强调这个问题。
  • 在 C++/CLI 中使用 System::String^,在 C# 中使用 string。两者都引用相同的类型,即 .net 字符串类型。我会在更新中告诉你。
  • 你是对的人!我总是喜欢把事情弄得比实际复杂,但是我搜索了一段时间并没有找到。也许这篇文章会帮助其他人不要犯同样的错误。
  • 谢谢。有时很难只见树木不见森林!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-11-06
  • 1970-01-01
  • 2017-11-30
  • 1970-01-01
  • 2022-01-14
  • 2011-07-15
  • 1970-01-01
相关资源
最近更新 更多