3

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?

user
  • 5,335
  • 7
  • 47
  • 63
Ezi
  • 2,212
  • 8
  • 33
  • 60
  • 2
    The code you posted is way too large for me to try to digest. If you have some specific question about how to read the data from the generated file, post an example of the code you wrote, and some details about what part of the other code you're trying to emulate. Without more specific information, I have no idea what exactly you're trying to do. – Jim Mischel May 03 '11 at 20:50

3 Answers3

4

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.

Tim Matthews
  • 5,031
  • 8
  • 38
  • 45
3

IntPtr is just a .NET type for void*. It doesn't imply any meaning by itself. You need to know what the memory contains, and make sure the .NET and the C sides are using the same memory layout.

There are two main ways you can interface between managed and unmanaged code.

One is C++/CLI (IJW). If you pin a managed object or array, then it can be passed into an unmanaged function. However, with complex types you can get into trouble, since .NET's memory layout isn't necessarily the same as what your C library expects. Check pin_ptr for more information.

The second popular method is using p/invoke, where you can marshal a C# struct (C++/CLI value struct) into a C struct, or even an array of those. You have a way of specifying the memory layout, whether string should be marshaled as MBCS or UTF-16, how the structure should be aligned, and so on. It is easy to call C functions directly from C# this way.

Tamas Demjen
  • 690
  • 1
  • 6
  • 8
  • 1
    Yes it is. However, in order to pass a managed pointer to a native function, first you have to pin its address, otherwise the garbage collector may move it around, which means the address would get invalidated. – Tamas Demjen May 04 '11 at 00:00
  • 1
    Also take a look at `Marshal.StructureToPtr`, which copies an `Object` into `IntPtr`. First you'd use `Marshal.AllocCoTaskMem` to allocate memory (to get the proper size, use `Marshal.SizeOf`, which is like sizeof in C), and `Marshal.FreeCoTaskMem` to free it. – Tamas Demjen May 04 '11 at 17:42
3

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 ); }
    }
}
Khadaji
  • 2,147
  • 2
  • 17
  • 19
  • Thank you for that code. can you please give me a small sample how to use it? thanks so much – Ezi May 05 '11 at 15:27
  • I will. It will take me a day or two to find it. – Khadaji May 06 '11 at 18:48
  • Ezi, I have found a smallish project that I wrote to test the BIOAPI. It doesn't do much, scans a fingerprint, saves to a file, reads the save back in for a verify. But I think it will be a good enough start to get you where you need to be. If you email me directly I will send it to you. (I am not particularly proud of the code though...I was pretty new to C# when I wrote it.) – Khadaji May 06 '11 at 19:48
  • Thank for that offer, what is your email address? – Ezi May 08 '11 at 04:04
  • 1
    My apologies, I thought it showed in my profile. win8128@aol.com – Khadaji May 08 '11 at 09:40