在C ++和C#之间传递vector struct

时间:2013-03-17 21:11:24

标签: c# c++ interop pinvoke

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

我的问题是:是否有可能对我的Windows点进行编组,以便将其作为向量传递到我的c ++代码中?我可以改变所有的代码(除了qwindows点,但我可以自己指出)。有一个解决方案,我不必创建一个c包装?我正在关注这个问题:How to call an unmanaged C++ function with a std::vector<>::iterator as parameter from C#?

非常感谢1 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();
    };
}

2 个答案:

答案 0 :(得分:4)

您可以将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包装器。

答案 1 :(得分:1)

我认为您应该只传递类型的数组,然后将它们转换为相对函数中的vector<T>或List。

您引用static extern INT calibrate_to_file()的事实也是如此 在C ++中,它是 VOID calibrate_to_file()

更新: 我认为你错过了函数的DLLEXPORT标签?