2013-03-23 98 views
0

嗨即时尝试从c#调用一些c + +代码。所以我跟着几个教程,amde我自己的dll,现在我从我的c#包装器调用它。事情是,我有一个函数接收一个指针,我似乎无法使它工作,视觉工作室只是显示我红色的错误,我不明白。有人能告诉我什么即时做错了吗? 我还有另外一个问题,如果C++中的函数调用其他函数,那么所有的数据都会保持不变吗?因为我传递的这个数组将在dll内部被操纵,之后,我将调用dll中的其他函数来获得结果 - 我担心数据在函数调用之间会丢失!c#和C++之间的指针 - p/invoke

谢谢!

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#包装

   [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

你可以尝试发布错误;) – cubuspl42 2013-03-23 20:15:52

+0

sry,“不能接受地址,获取大小或声明指向受管理类型的指针[namespace.points []] – virgula24 2013-03-23 20:23:23

+0

我认为这只是我的错,因为我不知道那么多关于指针,但我认为我做正确 – virgula24 2013-03-23 20:23:49

回答

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功能将是更加棘手的,因为你是返回一个指针的函数返回值。使用参数而不是函数返回值来返回该信息会更容易。

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

+0

mapear_kinect_porto由calibrate_to_file调用,我不从c#调用它。那就是为什么我问C++中的函数调用其他函数,所有的数据将保持不变!我会试试你的解决方案 – virgula24 2013-03-23 20:38:16