سؤال

ولدي البنية التالية في 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

وكذلك تم بحث موضوع مماثل على هذا السؤال ، واحدة من فقد كان الاستنتاج أن المعلمة 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;
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top