2015-07-10 69 views
2

我打電話從C#這樣的方法:轉換的IntPtr到ULONG陣列

[DllImport(@"pHash.dll", CallingConvention = CallingConvention.Cdecl)] 
public static extern IntPtr ph_dct_videohash(string file, ref int length); 

這裏是我如何可以讀取ulong陣列的方法,我從圖書館

ulong64* ph_dct_videohash(const char *filename, int &Length){ 

    CImgList<uint8_t> *keyframes = ph_getKeyFramesFromVideo(filename); 
    if (keyframes == NULL) 
     return NULL; 

    Length = keyframes->size(); 

    ulong64 *hash = (ulong64*)malloc(sizeof(ulong64)*Length); 
    //some code to fill the hash array 
    return hash; 
} 

調用來自IntPtr

+0

我認爲,如果你申報進口的返回類型爲'ULONG []'編譯器和/或者運行時會爲你做骯髒的工作。 – phoog

+1

這是一個內存泄漏,*有人*必須調用free()來再次釋放內存。您無法撥打該電話,因此您無法激活此功能。它的設計不好,它應該爲調用者提供通過緩衝區的選項。然後它很容易*和*高效。 –

+0

我試圖做到這一點,並得到錯誤 –

回答

2

雖然Marshal class不對付ulong小號直接,它確實要約提供任何方法,你Marshal.Copy(IntPtr, long[], int, int),你可以用它來獲得一個long數組,然後投中的值ulong秒。

對我來說,以下工作:

[DllImport("F:/CPP_DLL.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] 
static extern IntPtr uint64method(string file, ref int length); 

static ulong[] GetUlongArray(IntPtr ptr, int length) 
{ 
    var buffer = new long[length]; 
    Marshal.Copy(ptr, buffer, 0, length); 
    // If you're not a fan of LINQ, this can be 
    // replaced with a for loop or 
    // return Array.ConvertAll<long, ulong>(buffer, l => (ulong)l); 
    return buffer.Select(l => (ulong)l).ToArray(); 
} 

void Main() 
{ 
    int length = 4; 
    IntPtr arrayPointer = uint64method("dummy", ref length); 
    ulong[] values = GetUlongArray(arrayPointer, length); 
} 
+0

在長/永久對話中的錯誤值呢?很多返回的值的值大於long long的最大值 –

+0

@YuriSchneider請考慮:作爲64位整數的最大值的「0xFFFFFFFFFFFFFFFF」是作爲無符號整數的「18446744073709551615」。當轉換爲有符號整數時,如果使用的有符號數字表示是[二進制補碼],則該值變爲'-1'(https://en.wikipedia.org/wiki/Signed_number_representations#Two.27s_complement)(大多數系統使用二進制補碼)。這全是關於**代表**。底層數據在這裏沒有改變,因爲「ulong」和「long」都是64位整數。 – cubrr

+0

@YuriSchneider如果你想親自看看,請將其中一個數組的值設置爲「0xFFFFFFFFFFFFFFFFFF」。在C#中,Marshal.Copy是數組。然後看看它的價值。然後將它轉換爲「ulong」並再次查看該值。 – cubrr

2

只考慮使用不安全的代碼:

IntPtr pfoo = ph_dct_videohash(/* args */); 
unsafe { 
    ulong* foo = (ulong*)pfoo; 
    ulong value = *foo; 
    Console.WriteLine(value); 
} 
+0

添加到答案:如果您希望從數組中獲取所有值,只需創建一個新的ulong數組並使用for循環。例如'newArray [i] = foo [i];' – cubrr