i building managed wrapper in c# around native windows biometric framework, used access biometric sensors fingerprint sensors.
i have problems getting method work p/invoke: winbioidentify
hresult winapi winbioidentify( _in_ winbio_session_handle sessionhandle, _out_opt_ winbio_unit_id *unitid, _out_opt_ winbio_identity *identity, _out_opt_ winbio_biometric_subtype *subfactor, _out_opt_ winbio_reject_detail *rejectdetail ); the problem winbio_identity struct because contains union:
typedef struct _winbio_identity { winbio_identity_type type; union { ulong null; ulong wildcard; guid templateguid; struct { ulong size; uchar data[security_max_sid_size]; // constant 68 } accountsid; } value; } winbio_identity; here tried:
[structlayout(layoutkind.explicit, size = 76)] public struct winbioidentity { [fieldoffset(0)] public winbioidentitytype type; [fieldoffset(4)] public int null; [fieldoffset(4)] public int wildcard; [fieldoffset(4)] public guid templateguid; [fieldoffset(4)] public int accountsidsize; [fieldoffset(8)] [marshalas(unmanagedtype.byvalarray, sizeconst = 68)] public byte[] accountsid; } [dllimport("winbio.dll", entrypoint = "winbioidentify")] private extern static winbioerrorcode identify( winbiosessionhandle sessionhandle, out int unitid, out winbioidentity identity, out winbiobiometricsubtype subfactor, out winbiorejectdetail rejectdetail); public static int identify( winbiosessionhandle sessionhandle, out winbioidentity identity, out winbiobiometricsubtype subfactor, out winbiorejectdetail rejectdetail) { int unitid; var code = identify(sessionhandle, out unitid, out identity, out subfactor, out rejectdetail); winbioexception.throwonerror(code, "winbioidentify failed"); return unitid; } in form crashes typeloadexception complaining winbioidentity struct contains misaligned field @ offset 8. if leave out last field works, important data missing, of course.
any how handle case appreciated.
the guid in structure trouble-maker. 16 bytes long , therefore overlaps byte[]. clr disallows kind of overlap, prevents garbage collector identifying array object reference reliably. very important know whether or not array needs collected. gc has no way find out if structure contains guid or array.
you must give on byte[] , substitute value type gc not have deal possibly broken object reference. c# language has fixed keyword declare such kind of value types:
[structlayout(layoutkind.explicit)] unsafe public struct winbioidentity { //... [fieldoffset(8)] public fixed byte accountsid[68]; } note required unsafe keyword. project > properties > build > allow unsafe code option. in fact pretty unsafe, you'll want put assert in code before start using struct can sure no memory corruption can occur:
system.diagnostics.debug.assert(marshal.sizeof(typeof(winbioidentity)) == 76);
Comments
Post a Comment