在c++和c#之间传递vector结构体

本文关键字:vector 结构体 之间 c++ | 更新日期: 2023-09-27 18:04:16

我有c++非托管代码,我想从c#访问。所以我遵循了一些教程,我为我的项目建立了一个dll(只有一个类btw)。现在我想从c#中使用它,我正在使用p/invoke,如下所示。

我的问题是:是否有可能马歇尔我的Windows点,所以我可以把它作为一个矢量传递到我的c++代码?我可以改变所有的代码(除了qwindows点,但我可以提出我自己的观点)。是否有一个解决方案,我不需要创建一个c包装?我是以下这个问题:如何调用一个非托管的c++函数与std::vector<>::迭代器作为参数从c# ?

许多thanks1

ps,我找到了一个"解决方案",但我无法查看http://www.experts-exchange.com/Programming/Languages/C_Sharp/Q_21461195.html

c#

using Point = System.Windows.Point;
class CPlusPlusWrapper
{
    [DllImport("EmotionsDLL.dll", EntryPoint = "calibrate_to_file")]
    static extern int calibrate_to_file(vector<points> pontos);//marshall here
    [DllImport("EmotionsDLL.dll", EntryPoint = "calibration_neutral")]
    static extern int calibration_neutral();
    /// <summary>
    /// wraps c++ project into c#
    /// </summary>
    public void calibrate_to_file() { 
}

dll头

namespace EMOTIONSDLL
{
    struct points{
        double x;
        double y;
        double z;
    };
    #define db at<double>
    class DLLDIR EMOTIONS
    {
    public:
        EMOTIONS();
        CvERTrees *  Rtree ;

        vector<points> mapear_kinect_porto(vector<points> pontos);
        void calibrate_to_file(vector<points> pontos);
        int calibration_neutral();
        int EmotionsRecognition();
    };
}

在c++和c#之间传递vector结构体

您可以将c#数组封送到c++ std::vector中,但这将非常复杂,并且根本不是一个好主意,因为std::vector的布局和实现不能保证在不同的编译器版本之间是相同的。

你应该把形参改成指向数组的指针,并添加一个形参来指定数组的长度:

int calibrate_to_file(points* pontos, int length);

在c#中,将方法声明为接受一个数组并应用MarshalAs(UnmanagedType.LPArray)属性:

static extern int calibrate_to_file([MarshalAs(UnmanagedType.LPArray)]] Point[] pontos, int length);

还要注意你的c++ point结构与System.Windows.Point不兼容。后者没有z成员。

但是你的代码的一个更大的问题是,你不能真的期望dll导入一个实例方法,并能够像那样调用它。实例方法需要其类的实例,并且没有简单的方法可以从c#创建非com c++类的实例(这也不是一个好主意)。因此,您应该将其转换为COM类,或者为其创建c++/CLI包装器。

我认为你应该只是传递你的类型的数组,然后在相关函数中将它们转换为vector<T> 's或列表。

也可能是你引用了一个static extern INT calibrate_to_file()在c++中为VOID calibrate_to_file()

更新:我认为你缺少DLLEXPORT标签上的功能?