c++ - How to do memcpy in C# .Net CF with the following task -
hi trying convert c/c++ strcut c# , how fill structure member address of structure in c#?
c/c++ struct looks like:
typedef struct _ndisuio_query_oid { ndis_oid oid; ptchar ptcdevicename; uchar data[sizeof(ulong)]; } ndisuio_query_oid, *pndisuio_query_oid; typedef struct my_struct { //les have 2 variables... uint a; uint b; }my_stats, *pmy_stats; pndisuio_query_oid pqueryoid = null; pqueryoid = (pndisuio_query_oid)malloc(sizeof(ndisuio_query_oid)+ sizeof(my_stats)) ; pmy_stats statistics; pqueryoid->oid = uloidcode;//required oid pqueryoid->ptcdevicename = aub_name;//required string memcpy(pqueryoid->data, statistics, sizeof(my_stats));
my c# struct is:
[structlayout(layoutkind.sequential, charset = charset.unicode)] public struct _ndisuio_query_oid { public uint oid; [marshalas(unmanagedtype.lpwstr)] public string ptcdevicename; [marshalas(unmanagedtype.byvaltstr, sizeconst = sizeof(uint))] public string data; };
problem: how copy statistics structure data array in c#??
thanks :)
here's implementation (fyi, sdf contains of code , lot more)
internal class ndisqueryoid { protected const int ndisuio_query_oid_size = 12; protected byte[] m_data; public int size { get; private set; } public ndisqueryoid(byte[] data) { int extrasize = data.length; size = 8 + extrasize; m_data = new byte[size]; buffer.blockcopy(data, 0, m_data, dataoffset, data.length); } public ndisqueryoid(int extrasize) { size = ndisuio_query_oid_size + extrasize; m_data = new byte[size]; } protected const int oidoffset = 0; public uint oid { { return bitconverter.touint32(m_data, oidoffset); } set { byte[] bytes = bitconverter.getbytes(value); buffer.blockcopy(bytes, 0, m_data, oidoffset, 4); } } protected const int ptcdevicenameoffset = oidoffset + 4; public unsafe byte* ptcdevicename { { return (byte*)bitconverter.touint32(m_data, ptcdevicenameoffset); } set { byte[] bytes = bitconverter.getbytes((uint32)value); buffer.blockcopy(bytes, 0, m_data, ptcdevicenameoffset, 4); } } protected const int dataoffset = ptcdevicenameoffset + 4; public byte[] data { { byte[] b = new byte[size - dataoffset]; array.copy(m_data, dataoffset, b, 0, size - dataoffset); return b; } set { size = 8 + value.length; m_data = new byte[size]; buffer.blockcopy(value, 0, m_data, dataoffset, value.length); } } public byte[] getbytes() { return m_data; } public static implicit operator byte[](ndisqueryoid qoid) { return qoid.m_data; } }
note in usage, ndis ioct takes in pointer (most of ndis work done unsafe) you'd have adjustment there.
so if, example, you're querying bssid, know bssid data 36 bytes, i'd create this:
var queryoid = new ndisqueryoid(36);
then allocate name , call ndis (the production code has lot more checking this):
byte[] namebytes = system.text.encoding.unicode.getbytes(adaptername + '\0'); fixed (byte* pname = &namebytes[0]) { queryoid.ptcdevicename = pname; queryoid.oid = (uint)oid; var bytes = queryoid.getbytes(); ndis.deviceiocontrol(ioctl_ndisuio_query_oid_value, bytes, bytes); var result = new byte[queryoid.data.length]; buffer.blockcopy(queryoid.data, 0, result, 0, result.length); }
edit
so result
member above byte array of "result" of query. means , how interpret depends on oid queried was. example, if querying connected ssid (i.e. ndis_oid.ssid
), comes 4-byte length followed ascii-encoded name, you'd decipher this:
int len = bitconverter.toint32(data, 0); if (len > 0) { ssid = system.text.encoding.ascii.getstring(data, 4, len); }
but again, 1 specific oid. have handle every return case every incoming oid decide support.
Comments
Post a Comment