2015-07-10 2 views
2

Я звоню метод из C# как это:Преобразовать IntPtr в ULong массив

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

А вот метод, который я звоню из библиотеки

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; 
} 

Как я могу читать ulong массив от 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

Как насчет неправильных значений в длинном/улунговом разговоре? Множество возвращаемых значений имеет значения, превышающие длинное максимальное значение. –

+0

@YuriSchneider. Учтите это: '0xFFFFFFFFFFFFFFFF', что является максимальным значением для 64-битного целого, является« 18446744073709551615 »как целое число без знака. Когда применяется к значению целого числа, значение становится «-1», если используется подписанное числовое представление - [дополнение к двум] (https://en.wikipedia.org/wiki/Signed_number_representations#Two.27s_complement) (большинство систем используют два дополнения). Это все о ** представлении **. Исходные данные здесь не меняются, потому что 'ulong' и' long' являются 64-битными целыми числами. – cubrr

+0

@YuriSchneider Если вы хотите сами убедиться, задайте одно из значений вашего массива '0xFFFFFFFFFFFFFFFF'. В 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

Смежные вопросы