在C ++和C#之间传递向量结构体 [英] Passing vector struct between C++ and C#

查看:376
本文介绍了在C ++和C#之间传递向量结构体的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have c++ unmanaged code that i want to access from c#. So i followed some tutorials and i build a dll for my project (only one class btw). Now i want to use it from c#, and i'm using p/invoke as follows.

我的问题是:可以编组我的窗口点,所以我可以把它作为一个向量到我的c ++代码?我可以改变所有的代码(除了qwindows点,但我可以使自己的点)。有没有解决方案,我不必创建一个c包装?我按照这个问题:如何使用std :: vector<> :: iterator作为参数从C#调用非托管C ++函数?

my question is: is it possible to marshall my windows point so i can pass it as a vector into my c++ code? i can change all the code (except the qwindows point, but i can make my own point). IS there a solution where i dont have to create a c wrapper? i was following this question: How to call an unmanaged C++ function with a std::vector<>::iterator as parameter from C#?

很多谢谢
ps,i找到了一个解决方案,但我无法查看它 http://exex -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 header

dll header

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 ++ std :: vector,但它会非常复杂,并不是一个好主意,因为std :: vector的布局和实现不保证在编译器版本之间是一样的。

You could marshal a C# array as a C++ std::vector, but it would be very complicated and is simply not a good idea because the layout and implementation of std::vector is not guaranteed to be the same between compiler versions.

而是应该将参数更改为指向数组的指针,并添加一个指定数组长度的参数:

Instead you should change the parameter into a pointer to an array, and add a parameter specifying the length of the array:

int calibrate_to_file(points* pontos, int length);

在C#中声明该方法为一个数组并应用MarshalAs(UnmanagedType.LPArray)

And in C# declare the method as taking an array and apply the MarshalAs(UnmanagedType.LPArray) attribute:

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

请注意,您的C ++ 结构与System.Windows 。点。后者没有 z 成员。

Note also that your C++ point structure is not compatible with System.Windows.Point. The latter doesn't have a z member.

但是更大的问题是,你不能真正期望DLL-导入一个实例方法,并能够像这样调用它。实例方法需要其类的实例,并且没有简单的方法来创建一个非COM C ++类的实例从C#(并且也不是一个好主意)。因此,你应该把它变成一个COM类,或者为它创建一个C ++ / CLI包装。

But a bigger issue with your code is that you can't really expect to DLL-import an instance method and be able to call it just like that. An instance method needs an instance of its class, and there's no easy way to create an instance of a non-COM C++ class from C# (and is also not a good idea). Therefore, you should turn this into a COM class, or create a C++/CLI wrapper for it.

这篇关于在C ++和C#之间传递向量结构体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆