c#和c ++之间的指针 - p / invoke

时间:2013-03-23 20:14:38

标签: c# c++ pointers interop pinvoke

我试图从c#调用一些c ++代码。所以我按照几个教程,使用自己的dll,现在我从我的c#wrapper中调用它。事情是,我有一个接收指针的功能,我似乎无法使它工作,视觉工作室只是向我显示我不太了解的红色错误。谁能告诉我我做错了什么? 我有另一个问题,如果c ++中的函数调用其他函数,所有数据将保持完整吗?因为我传递的这个数组将在dll中被操作,然后,我将从dll调用其他函数来获得结果 - 我担心函数调用之间的数据会丢失!

谢谢!

dll .h        #include

   #include <stdio.h> 

   #include <stdlib.h> 

   #include <math.h> 

   #include <string> 

   #include <vector> 

   #include <fstream> 

   #include <sstream> 

   #include <cstring> 

   #include <fstream>

   #include <iomanip> 

   #include <cstdlib> 

   #include <string> 

   #include <cstring> 

   #include "opencv\ml.h"

   struct points{
    double x;
    double y;
    double z;
   };

#define db at<double>


   extern "C" __declspec(dllexport) points * mapear_kinect_porto(points pontos[]);


   CvERTrees *  Rtree ;


   extern "C" __declspec(dllexport)     void calibrate_to_file(points pontos[]);

   extern "C" __declspec(dllexport)     int calibration_neutral();

   extern "C" __declspec(dllexport)       int EmotionsRecognition();

c#wrapper

             [System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct points
{

    /// double
    public double x;

    /// double
    public double y;

    /// double
    public double z;
}


class CPlusPlusWrapper
{

/// Return Type: void
    ///pontos: points*
    [System.Runtime.InteropServices.DllImportAttribute("DLLTUT.dll", EntryPoint =  "calibrate_to_file")]
    public static extern void calibrate_to_file(ref points pontos);
    public unsafe void calibrate_file()
    {

        points[] shit = new points[8];
        points*[] pBLA; //error here!!!!
        pBLA = &shit;
   //            calibrate_to_file(pbla);
    }

}

顺便说一句,我使用了p / invoke助手,我得到了这个

public partial class NativeConstants {

/// db -> at<double>
/// Error generating expression: Expression is not parsable.  Treating value as a raw string
public const string db = "at<double>";
}

[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public struct points {

/// double
public double x;

/// double
public double y;

/// double
public double z;
}

public partial class NativeMethods {

/// Return Type: points*
///pontos: points*
[System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="mapear_kinect_porto")]
public static extern  System.IntPtr mapear_kinect_porto(ref points pontos) ;


/// Return Type: void
///pontos: points*
[System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="calibrate_to_file")]
public static extern  void calibrate_to_file(ref points pontos) ;


/// Return Type: int
[System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="calibration_neutral")]
public static extern  int calibration_neutral() ;


/// Return Type: int
[System.Runtime.InteropServices.DllImportAttribute("<Unknown>", EntryPoint="EmotionsRecognition")]
public static extern  int EmotionsRecognition() ;

}

1 个答案:

答案 0 :(得分:2)

您似乎正在尝试调用名为calibrate_to_file的函数。收到points的数组。 p / invoke是:

[DllImportAttribute("DLLTUT.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern void calibrate_to_file(points[] pontos);

绝对不需要不安全的代码。只需在您的调用代码中创建一个points[]类型的数组,然后调用calibrate_to_file

您需要确保调用约定匹配。由于您未在C ++代码中指定调用约定,因此我假设使用了默认值cdecl

结构可以简单地声明为

[StructLayout(LayoutKind.Sequential)]
public struct points
{
    public double x;
    public double y;
    public double z;
}

mapear_kinect_porto函数会变得更棘手,因为您返回一个指针作为函数返回值。使用参数而不是函数返回值来返回该信息会更容易。

我最好的建议就是将这个问题分解成小块。获得最简单的功能。然后转到下一个功能。等等。不要试图一次解决整个问题。然后,当它不可避免地失败时,你不会知道在哪里寻找错误。