简体   繁体   中英

Convert intptr to ulong array

I am calling a method from C# like this:

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

And here is the method I am calling from the library

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

How can I read the ulong array from the IntPtr ?

While the Marshal class doesn't provide any methods for dealing with ulong s directly, it does offer you Marshal.Copy(IntPtr, long[], int, int) which you can use to get a long array and then cast the values to ulong s.

The following works for me:

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

Consider just using unsafe code:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM