مجموعة المشير C ++ البنية في C #
-
06-07-2019 - |
سؤال
ولدي البنية التالية في C ++:
#define MAXCHARS 15
typedef struct
{
char data[MAXCHARS];
int prob[MAXCHARS];
} LPRData;
وظيفة أنني ف / استدعاء إلى الحصول على مجموعة من 3 من هذه الهياكل:
void GetData(LPRData *data);
في C ++ أود فقط أن تفعل شيئا من هذا القبيل:
LPRData *Results;
Results = (LPRData *)malloc(MAXRESULTS*sizeof(LPRData));
GetData( Results );
وسوف يعمل على ما يرام، ولكن في C # أنا لا يمكن أن يبدو للحصول على عمل. لقد خلق C # البنية مثل هذا:
public struct LPRData
{
/// char[15]
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
public string data;
/// int[15]
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 15)]
public int[] prob;
}
وإذا كان لي تهيئة مجموعة من 3 من تلك (وكل ما لديهم صفائف فرعية) وتمريرها إلى هذا:
GetData(LPRData[] data);
وويعود مع النجاح، ولكن البيانات في مجموعة LPRData لم يتغير.
ولقد حاولت حتى لإنشاء صفيف بايت الخام حجم من 3 ليالي LPRData وتمرير ذلك إلى تعريف الدالة مثل هذا:
وGetData ([] بايت البيانات)؛
ولكن في هذه الحالة سوف أحصل على "بيانات" سلسلة من بنية LPRData الأول جدا، ولكن لا شيء بعد ذلك، بما في ذلك "غالبا" مجموعة من نفس LPRData.
وأي أفكار لكيفية التعامل مع هذا صحيح؟
المحلول
وسوف أحاول إضافة بعض سمات decloration البنية بك
[StructLayout(LayoutKind.Sequential, Size=TotalBytesInStruct),Serializable]
public struct LPRData
{
/// char[15]
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
public string data;
/// int[15]
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 15)]
public int[] prob;
}
* ليس المقصود ملاحظة TotalBytesInStruct لتمثيل متغير
وJaredPar صحيح أيضا أن استخدام فئة IntPtr يمكن أن تكون مفيدة، ولكنها كانت لحظة تماما منذ أن كنت قد استخدمت PInvoke لذلك أنا صدئ.
نصائح أخرى
وخدعة واحدة عند التعامل مع مؤشرات هو مجرد استخدام IntPtr. ثم يمكنك استخدام Marshal.PtrToStructure على المؤشر وزيادة بناء على حجم هيكل للحصول على النتائج.
static extern void GetData([Out] out IntPtr ptr);
LPRData[] GetData()
{
IntPtr value;
LPRData[] array = new LPRData[3];
GetData(out value);
for (int i = 0; i < array.Length; i++)
{
array[i] = Marshal.PtrToStructure(value, typeof(LPRData));
value += Marshal.SizeOf(typeof(LPRData));
}
return array;
}
ووإمكانية التشغيل المتداخل مساعد PInvoke قد تساعد. http://clrinterop.codeplex.com/releases/view/14120
هل بمناسبة المعلمة GetData مع OutAttribute و>
<اقتباس فقرة>والجمع بين InAttribute و OutAttribute مفيدة بشكل خاص عندما يطبق على المصفوفات وتنسيقها، أنواع غير blittable. المتصلين رؤية التغييرات التي المستدعى يجعل لهذه الأنواع فقط عند تطبيق كل الصفات.
اقتباس فقرة> وكذلك تم بحث موضوع مماثل على هذا السؤال ، واحدة من فقد كان الاستنتاج أن المعلمة CharSet
اسمه يجب تعيين CharSet.Ansi
. وإلا، فإننا لن تقدم مجموعة wchar_t
بدلا من مجموعة char
. وهكذا، فإن الرمز الصحيح سيكون على النحو التالي:
[Serializable]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct LPRData
{
[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 15)]
public string data;
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 15)]
public int[] prob;
}