2013-03-23 99 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