Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get IntPtr pointer from object

I'm working on a finger-print device, the manufacture (Upek) gave me a c++ BSAPI.dll so I need to use wrappers to get this to work in .net.

I'm able to work with it all from in-memory, I could grab and match the finger prints.

Now I'm stuck trying to get the data out to a file and then loading it back in to memory and get the IntPtr.

Here there's a c++ sample on how to export and import from a file. but I don't know how to read it.

Any help is appreciated Thanks all


This is what I have and works great: enter image description here

Now I need two things 1. Take that bufBIR save it to a database. 2. Take the data I saved and pass it in to the abs_verify.

How can this be done?

like image 801
Ezi Avatar asked Oct 22 '25 09:10

Ezi


2 Answers

I don't know what the body of the question means but to answer the title :

How can I get an IntPtr from object?

This is intentionally made to require a little bit of work, with good reason. The garbage collector can often re locate objects within memory so can and only be done by 'pinning' it. To do this you must create a GCHandle with GCHandleType 'Pinned' and then you can call GCHandle.AddrOfPinnedObject. This will throw an Exception if it is not pinned.

Also you should note that GCHandle.ToIntPtr returns the value of the handle not the address of the object. This is basically used to have a single integral value that can be passed easily around before reconstructing the GCHandle.

like image 176
Tim Matthews Avatar answered Oct 23 '25 23:10

Tim Matthews


Here is C# code I got (I think from the BIOAPI sample code) a long time ago to interface with BioAPI. The DoMarshall method returns an IntPtr pointing to allocated memory large enough to hold the array.

I have not worked with Managed C++, so I am not sure what changes are needed, but maybe it will point you in the right direction. I was working with UPEK at the time. I hope this helps...

    [Serializable]
[StructLayout(LayoutKind.Sequential)]
public class BioAPI_DATA 
{
    public uint Length = 0;
    public byte[] Data = null;
    public BioAPI_DATA() {}
    public BioAPI_DATA(uint length, byte[] data) { Length = length; Data = data; }

    public IntPtr DoMarshal(ref int size)
    {
        IntPtr ptr;
        IntPtr ptrData = IntPtr.Zero;
        int ofs = 0;

        size = Marshal.SizeOf(Type.GetType("System.Int32")) + 
               Marshal.SizeOf(Type.GetType("System.IntPtr"));

        ptr = Marshal.AllocCoTaskMem( size );
        Marshal.WriteInt32(ptr, ofs, (int) Length);
        ofs += Marshal.SizeOf(Type.GetType("System.Int32"));
        if (Data != null) 
        {
            ptrData = Marshal.AllocCoTaskMem( Data.Length );
            Marshal.Copy(Data, 0, ptrData, Data.Length);
        }
        Marshal.WriteIntPtr(ptr, ofs, ptrData);
        return ptr;
    }

    public void DoUnmarshal(IntPtr ptr, ref int size, bool fDeleteOld)
    {
        int ofs = 0;
        size = Marshal.SizeOf(Type.GetType("System.Int32")) + 
               Marshal.SizeOf(Type.GetType("System.IntPtr"));
        Length =  (uint) Marshal.ReadInt32( ptr, ofs );
        ofs += Marshal.SizeOf(Type.GetType("System.Int32"));

        if (Length == 0) 
        {
            if (Data != null) Data = null;
            return;
        }

        IntPtr ptr2 = Marshal.ReadIntPtr(ptr, ofs);

        if (Data == null || Data.Length != Length) Data = new byte[Length];
        Marshal.Copy(ptr2, Data, 0, (int) Length);
        if (fDeleteOld)  { if (ptr != IntPtr.Zero) Marshal.FreeCoTaskMem( ptr ); }
    }
}
like image 44
Khadaji Avatar answered Oct 23 '25 23:10

Khadaji



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!