2015-01-20 260 views
-2

我已經能夠在C閱讀功能包含這樣的方法++ DLL:調用函數

extern "C" { __declspec(dllexport) Vector4 resta(Vector4 vector1,Vector4 vector2); } 

我一直在考慮一個dll實現以下功能:

extern "C"{ __declspec(dllexport) void pinverse(Vector4 skel[20], Vector4 result[20]); } 

此功能需要20個的Vector4的數組變量和使用犰狳程序計算矩陣的僞逆,但我沒有被告知哪些例程準確,並從C#執行功能時,我得到一個全零矩陣。我也執行了C++中的函數,同時將armadillo dll保存在projecto文件夾中,並將它們添加到鏈接器輸入中,並且得到了非零的結果。所以問題是,我應該如何包含應該在c#代碼中執行的armadillo例程?爲什麼我沒有看到任何錯誤消息,如果在DLL中的例程沒有找到庫中的其他例程?

在我使用C#的語法是:

[DllImport("C:\\Users\\PALMA\\Documents\\Visual Studio 2013\\Projects\\PruebaTest\\PruebaTest\\PruebaDll.dll", CallingConvention = CallingConvention.Cdecl)] 
    public static unsafe extern void pinverse(Vector4[] skel, Vector4[] result); 

和的Vector4是這樣定義的結構:}

public struct Vector4{ 

    public static bool operator !=(Vector4 vector1, Vector4 vector2); 
    public static bool operator ==(Vector4 vector1, Vector4 vector2); 

    public float W { get; set; } 
    public float X { get; set; } 
    public float Y { get; set; } 
    public float Z { get; set; } 

    public override bool Equals(object obj); 
    public bool Equals(Vector4 vector); 
    public override int GetHashCode(); 

在C#然後我繼續創建一個類如下調用導入函數:

public static Vector4[] ProbarArmadillo(Vector4[] resultado) 
     { 
    Vector4[] skel1=new Vector4[20]; 
    Vector4[] skel2=new Vector4[20]; 

    skel1[0].X = (float)-0.505401; skel1[0].Y = (float)-0.0968128; skel1[0].Z = (float)2.54701; skel1[0].W = 1; 
    skel1[1].X = (float)-0.547074; skel1[1].Y = (float)-0.0348387; skel1[1].Z = (float)2.5876; skel1[1].W = 1; 
    skel1[2].X = (float)-0.532013; skel1[2].Y = (float)0.323909; skel1[2].Z = (float)2.60893; skel1[2].W = 1; 
    skel1[3].X = (float)-0.468823; skel1[3].Y = (float)0.514958; skel1[3].Z = (float)2.63824; skel1[3].W = 1; 
    skel1[4].X = (float)-0.642778; skel1[4].Y = (float)0.221897; skel1[4].Z = (float)2.49321; skel1[4].W = 1; 
    skel1[5].X = (float)-0.765644; skel1[5].Y = (float)0.172945; skel1[5].Z = (float)2.27342; skel1[5].W = 1; 
    skel1[6].X = (float)-0.793357; skel1[6].Y = (float)0.258069; skel1[6].Z = (float)2.04539; skel1[6].W = 1; 
    skel1[7].X = (float)-0.802389; skel1[7].Y = (float)0.291529; skel1[7].Z = (float)2.01768; skel1[7].W = 1; 
    skel1[8].X = (float)-0.405216; skel1[8].Y = (float)0.194607; skel1[8].Z = (float)2.75541; skel1[8].W = 1; 
    skel1[9].X = (float)-0.297749; skel1[9].Y = (float)0.153036; skel1[9].Z = (float)2.85184; skel1[9].W = 1; 
    skel1[10].X = (float)-0.164521; skel1[10].Y = (float)0.228597; skel1[10].Z = (float)2.93223; skel1[10].W = 1; 
    skel1[11].X = (float)-0.105644; skel1[11].Y = (float)0.269457; skel1[11].Z = (float)2.98627; skel1[11].W = 1; 
    skel1[12].X = (float)-0.551655; skel1[12].Y = (float)-0.15617; skel1[12].Z = (float)2.48071; skel1[12].W = 1; 
    skel1[13].X = (float)-0.605082; skel1[13].Y = (float)-0.55405; skel1[13].Z = (float)2.37626; skel1[13].W = 1; 
    skel1[14].X = (float)-0.659974; skel1[14].Y = (float)-0.880765; skel1[14].Z = (float)2.35654; skel1[14].W = 1; 
    skel1[15].X = (float)-0.597098; skel1[15].Y = (float)-0.914582; skel1[15].Z = (float)2.29637; skel1[15].W = 1; 
    skel1[16].X = (float)-0.448527; skel1[16].Y = (float)-0.184062; skel1[16].Z = (float)2.58483; skel1[16].W = 1; 
    skel1[17].X = (float)-0.49097; skel1[17].Y = (float)-0.628932; skel1[17].Z = (float)2.57352; skel1[17].W = 1; 
    skel1[18].X = (float)-0.515788; skel1[18].Y = (float)-0.962651; skel1[18].Z = (float)2.54876; skel1[18].W = 1; 
    skel1[19].X = (float)-0.476598; skel1[19].Y = (float)-1.02878; skel1[19].Z = (float)2.53682; skel1[19].W = 1; 

    skel2[0].X = (float)-0.505401; skel2[0].Y = (float)-0.0968128; skel2[0].Z = (float)2.54701; skel2[0].W = 1; 
    skel2[1].X = (float)-0.547074; skel2[1].Y = (float)-0.0348387; skel2[1].Z = (float)2.5876; skel2[1].W = 1; 
    skel2[2].X = (float)-0.532013; skel2[2].Y = (float)0.323909; skel2[2].Z = (float)2.60893; skel2[2].W = 1; 
    skel2[3].X = (float)-0.468823; skel2[3].Y = (float)0.514958; skel2[3].Z = (float)2.63824; skel2[3].W = 1; 
    skel2[4].X = (float)-0.642778; skel2[4].Y = (float)0.221897; skel2[4].Z = (float)2.49321; skel2[4].W = 1; 
    skel2[5].X = (float)-0.765644; skel2[5].Y = (float)0.172945; skel2[5].Z = (float)2.27342; skel2[5].W = 1; 
    skel2[6].X = (float)-0.793357; skel2[6].Y = (float)0.258069; skel2[6].Z = (float)2.04539; skel2[6].W = 1; 
    skel2[7].X = (float)-0.802389; skel2[7].Y = (float)0.291529; skel2[7].Z = (float)2.01768; skel2[7].W = 1; 
    skel2[8].X = (float)-0.405216; skel2[8].Y = (float)0.194607; skel2[8].Z = (float)2.75541; skel2[8].W = 1; 
    skel2[9].X = (float)-0.297749; skel2[9].Y = (float)0.153036; skel2[9].Z = (float)2.85184; skel2[9].W = 1; 
    skel2[10].X = (float)-0.164521; skel2[10].Y = (float)0.228597; skel2[10].Z = (float)2.93223; skel2[10].W = 1; 
    skel2[11].X = (float)-0.105644; skel2[11].Y = (float)0.269457; skel2[11].Z = (float)2.98627; skel2[11].W = 1; 
    skel2[12].X = (float)-0.551655; skel2[12].Y = (float)-0.15617; skel2[12].Z = (float)2.48071; skel2[12].W = 1; 
    skel2[13].X = (float)-0.605082; skel2[13].Y = (float)-0.55405; skel2[13].Z = (float)2.37626; skel2[13].W = 1; 
    skel2[14].X = (float)-0.659974; skel2[14].Y = (float)-0.880765; skel2[14].Z = (float)2.35654; skel2[14].W = 1; 
    skel2[15].X = (float)-0.597098; skel2[15].Y = (float)-0.914582; skel2[15].Z = (float)2.29637; skel2[15].W = 1; 
    skel2[16].X = (float)-0.448527; skel2[16].Y = (float)-0.184062; skel2[16].Z = (float)2.58483; skel2[16].W = 1; 
    skel2[17].X = (float)-0.49097; skel2[17].Y = (float)-0.628932; skel2[17].Z = (float)2.57352; skel2[17].W = 1; 
    skel2[18].X = (float)-0.515788; skel2[18].Y = (float)-0.962651; skel2[18].Z = (float)2.54876; skel2[18].W = 1; 
    skel2[19].X = (float)-0.476598; skel2[19].Y = (float)-1.02878; skel2[19].Z = (float)2.53682; skel2[19].W = 1; 

    // pinverse(skel1, Resultado); 
    pinverse(skel1, resultado); 
    return resultado; 
} 

最後我用的功能主要是這樣的:

 Vector4[] resultado = new Vector4[20]; 

     resultado= Procesar.ProbarArmadillo(resultado); 
     Recorder.SaveArmadillo(resultado); 

Recorder是穿一個txt文件的輸出類,但該文件顯示了一個全零矩陣。

+0

你有任何C#代碼嗎?什麼是'Vector4'? – 2015-01-20 21:08:32

+0

你是怎麼從C#調用這個的?你使用的是什麼PInvoke簽名? – 2015-01-20 21:21:52

+0

[DllImport(「C:\\ Users \\ PALMA \\ Documents \\ Visual Studio 2013 \\ Projects \\ PruebaTest \\ PruebaTest \\ PruebaDll.dll」,CallingConvention = CallingConvention.Cdecl)] public static unsafe extern void pinverse(Vector4 [] skel,Vector4 []結果); – 2015-01-21 01:07:32

回答

2

我認爲你的結構聲明有點不合適。我不確定編組人員如何處理自動實現的屬性。我會避免他們。我會有這樣的結構:

[StructLayout(LayoutKind.Sequential)] 
public struct Vector4 
{ 
    public float W; 
    public float X; 
    public float Y; 
    public float Z; 
} 

而p/invoke應該提供方向屬性。也不需要unsafe,我假設你在隨機嘗試事情時添加了它。

[DllImport(dllname, CallingConvention = CallingConvention.Cdecl)] 
public static extern void pinverse(
    [In, MarshalAs(UnmanagedType.LPArray, SizeConst = 20)] 
    Vector4[] skel, 
    [Out, MarshalAs(UnmanagedType.LPArray, SizeConst = 20)] 
    Vector4[] result 
); 
+0

試過了,像魅力一樣工作,不需要指針,結構也沒有改變。 – 2015-01-29 18:03:25

+0

我可以想象這個結構的工作原理。我個人更喜歡明確,但沒關係。感謝你的接納。 – 2015-01-29 18:14:03

0

我終於搞定了。我改寫了這樣的C++函數:

void inversa(Vector4 *skel1, Vector4 *result){ 
fmat temp(20, 4); 

for (int i = 0; i < 20; i++){ 
    temp(i, 0) = (skel1 + i)->x; temp(i, 1) = (skel1 + i)->y; temp(i, 2) = (skel1 + i)->z; temp(i, 3) = (skel1 + i)->w; 
} 

fmat B = pinv(temp); 
for (int j = 0; j < 20; j++){ 
    (result + j)->x = B(0, j); (result + j)->y = B(1, j); (result + j)->z = B(2, j); (result + j)->w = B(3, j); 
} 

} 

然後編譯它在一個dll項目是這樣的:

namespace pdll 
{ 

extern "C"{ __declspec(dllexport) void mensaje(); } 
extern "C"{ __declspec(dllexport) void promedio(Vector4 skel1[20], Vector4 skel2[20], Vector4 prom[20]); } 
extern "C"{ __declspec(dllexport) void pinverse(Vector4 skel[20], Vector4 result[20]); } 
extern "C"{ __declspec(dllexport) void inversa(Vector4 *skel1, Vector4 *result); } 

} 

和進口在C#這樣的:

[DllImport("C:\\Users\\PALMA\\Documents\\Visual Studio 2010\\Projects\\LeerDLL\\PruebaDll.dll", CallingConvention = CallingConvention.Cdecl)] 
    public static unsafe extern void inversa(Vector4* skel1, Vector4* result); 

然後創建一個這種包裝功能如下:

public static unsafe Vector4[] Inverse(Vector4[] esqueleto, Vector4[] matrizinversa) { 

    fixed (Vector4* skeletonpointer = esqueleto, inversepointer = matrizinversa) 
    { 
     inversa(skeletonpointer,inversepointer); 
    } 

    return matrizinversa; 
} 

並使用它是這樣的:

 Vector4[] resultado = new Vector4[20]; 

     resultado= Procesar.ProbarArmadillo(resultado); 
     Recorder.SaveArmadillo(resultado); 

和輸出來的。txt文件是:

enter image description here

我試過被引用的參數傳遞給函數的唯一的事情,把這個想法從漢斯帕桑特,批評誰路過的價值。

希望這有助於任何人嘗試從c#使用犰狳例程。

+0

這個答案讓我難過 – 2015-01-22 19:30:10

+0

問候大衛,我想知道爲什麼這個答案讓你難過。 – 2015-01-23 13:15:07

+0

這對未來的讀者不會有用。不必要地使用不安全。沒有真正解決這個問題。 – 2015-01-23 13:16:44