שימוש ב-unsafe mode ב-C# core

שיווקי

New member
שימוש ב-unsafe mode ב-C# core

שלום.
ב-C# core,
אני מקצה שטח זיכרון למשתנה מסוג מערך ushort בגודל 1G.
אני רוצה להעביר אותו למשתנה מסוג מערך short בגודל 1G.

ניסיתי את הקוד להלן, אך ללא הועיל:
קוד:
unsafe
{
    ushort[] x = new ushort[1000000000];
    fixed (ushort* y = &x[0])
    {
        IntPtr p = (IntPtr)y;
        short[] s = (short[])Marshal.PtrToStructure(p, typeof(short[]));
    }
}
כיוון שמחזיר לי הודעת שגיאה:
No parameterless constructor defined for this object.

חשוב לי לא להקצות שטח זיכרון נוסף, וחשוב לי להחזיר למשתנה managed שאוכל להשתמש בו בקוד.

לו היה union כמו ב-C++ (רק שתומך ב-array) זה היה מעולה.

איך ניתן לעשות כן?

תודה.
 

ai21

New member
למה להיות חורני ולהשתמש במשתנים? תבנה CLASS כמו מלך!

בערך ככה:
קוד:
 unsafe class FixedArray<T> where T : unmanaged
{
    T* arrayPtr;

    public T this[int i]
    {
        get { return *(arrayPtr + i); }
        set { *(arrayPtr + i) = value; }
    }
    public FixedArray(ushort[] Arr)
    {
        arrayPtr = (T*)Arr;
    }
    ~FixedArray()
    {
        Marshal.FreeHGlobal((IntPtr)arrayPtr);
    }
}
 

שיווקי

New member
בלי קשר class - חשוב שיפתור עניין, ואם כן, אז מעולה


חשוב יותר הקונספט. כל הקוד גם כך בתוך class...

אם אני מחליף את ה-T ב-short[] (זה מה שאני רוצה לבצע המרה).

קוד:
unsafe class FixedArray
{
    short[]* arrayPtr;

    public short[] this[int i]
    {
        get { return *(arrayPtr + i); }
        set { *(arrayPtr + i) = value; }
    }
    public FixedArray(ushort[] Arr)
    {
        arrayPtr = (short[]*)Arr;
    }
    ~FixedArray()
    {
        Marshal.FreeHGlobal((IntPtr)arrayPtr);
    }
}

האם הנ"ל מתקמפל? כתבת דווקא unmanaged עבור ה-type.

חשוב לי גם לדעת להתייחס למשתנה שהוא managed (זה ה-short[]) כיוון שאני רוצה להתייחס אליו ככזה, וגם אני מעביר אותו לפונקציות מספריות שהן 3rd party.
ההתייחסות היא לכל המערך ולא לאיבר ספציפי במערך (אם המערך הוא מסוג short[] פחות מעניין אם אני פונה לאיבר ה-15, אלא להעביר את המערך לפונקציה נוספת חיצונית), וברור שלא לבצע הקצאת זיכרון לאותו המשתנה (שלא יתפוס לי עוד 1G מיותרים, אם אני יכול לבצע casting או משהו אחר שפותר את העניין).

תודה.
 

שיווקי

New member
בבדיקה ראשונית, לא ממש נראה שפותר עניין.

הדוגמה שנתת לא מחזירה את כל המערך.
אני מעוניין ב:
short[] s;

ואילו ה-class שהצגת יכול להחזיר איבר בודד ולא את כל המערך (אני צריך להעביר את כל המערך כפרמטר לפונקציה אחרת).
 

selalerer

New member
אולי יש דרך לעקוף את הבעיה. למה אתה צריך מערך short?

מה אתה עושה איתו?
 
למעלה