Managed Unmanaged memory
От: RArthur  
Дата: 11.07.13 12:16
Оценка:
Привет,

Есть код на C# который вызывает С-ую функцию

extern "C" __declspec(dllexport) void __stdcall GetTick(TickData* data, int count)
{
    for (int i = 0; i < count; i++)
    {
        data[i].value = (i + 1)*5;
        strcpy_s(data[i].name, "aaaaaaaaaaaaa");
    }
}



[StructLayout(LayoutKind.Sequential, Pack = 1)]
unsafe struct TickData
{
    public int value;

    public fixed byte name[100];
}


public class FixedUnsafeAllocate
{
    [DllImport("NativeC.dll")]
    static extern int GetTick(IntPtr data, int count);

    public void Execute()
    {
        var data = new TickData[Program.Count];
        var pTickData = GCHandle.Alloc(data, GCHandleType.Pinned);
        try
        {

            var poiner = pTickData.AddrOfPinnedObject();
            var result = GetTick(poiner, Program.Count);

            for (var i = 0; i < Program.Count; i++)
                unsafe
                {
                    fixed (byte* name = data[i].name)
                    {
                        var value = new string((sbyte*) name);
                    }
                }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        finally
        {
            if(pTickData.IsAllocated)
                pTickData.Free();
        }
    }
}


Скажите пожалйста, могут ли быть проблемы и если да то где.

С Уважением,
RArthur
Re: Managed Unmanaged memory
От: hardcase Пират http://nemerle.org
Дата: 11.07.13 13:54
Оценка:
Здравствуйте, RArthur, Вы писали:

Зачем тебе GCHandle? Почему бы не использовать блок fixed.
/* иЗвиНите зА неРовнЫй поЧерК */
Re: Managed Unmanaged memory
От: hardcase Пират http://nemerle.org
Дата: 11.07.13 13:56
Оценка:
Здравствуйте, RArthur, Вы писали:

Кстати, а чем не угодило так:
  [DllImport("NativeC.dll")]
  static extern int GetTick(out TickData data, int count);
/* иЗвиНите зА неРовнЫй поЧерК */
Re[2]: Managed Unmanaged memory
От: Sinix  
Дата: 12.07.13 05:34
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Кстати, а чем не угодило так:


По памяти (могу ошибаться) можно совсем упростить жизнь (маршаллинг возьмёт на себя всю возню с fixed/unsafe):
    [DllImport("NativeC.dll")]
    static extern int GetTick([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] TickData[] data);


Плюс, меня смущает маршаллинг строки. Там нужно или Marshal.PtrToStringAnsi(name), или
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct TickData
{
    public int value;

    [MarshalAs(UnmanagedType.LPStr, SizeConst = 50)]
    public string name;
}
Re[2]: Managed Unmanaged memory
От: RArthur  
Дата: 12.07.13 08:18
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, RArthur, Вы писали:


H>Зачем тебе GCHandle? Почему бы не использовать блок fixed.


Привет,

Использую GCHandle чтоб GC не перемещал бы данные, объем которых слишком ольшой — около 10000000. Потому если GC переместит их, указатель в С++ уже не будет валидным.

С Уважением
Артур
Re[2]: Managed Unmanaged memory
От: RArthur  
Дата: 12.07.13 08:19
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, RArthur, Вы писали:


H>Кстати, а чем не угодило так:

H>
H>  [DllImport("NativeC.dll")]
H>  static extern int GetTick(out TickData data, int count);
H>


Привет,

Ну раз работаю с unsafe, просто поэтому так и написал.

Спасибо
Re[3]: Managed Unmanaged memory
От: RArthur  
Дата: 12.07.13 08:21
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, hardcase, Вы писали:


H>>Кстати, а чем не угодило так:


S>По памяти (могу ошибаться) можно совсем упростить жизнь (маршаллинг возьмёт на себя всю возню с fixed/unsafe):

S>
S>    [DllImport("NativeC.dll")]
S>    static extern int GetTick([MarshalAs(UnmanagedType.LPArray, SizeParamIndex=0)] TickData[] data);
S>


S>Плюс, меня смущает маршаллинг строки. Там нужно или Marshal.PtrToStringAnsi(name), или

S>
S>[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
S>public struct TickData
S>{
S>    public int value;

S>    [MarshalAs(UnmanagedType.LPStr, SizeConst = 50)]
S>    public string name;
S>}
S>


Привет,

Согласен с Marshal-гом, только вот проблема при больших данных, Marshal-инг работает в несколько раз медленнее.

Спасибо
Re[2]: Managed Unmanaged memory
От: RArthur  
Дата: 12.07.13 08:30
Оценка:
Здравствуйте, hardcase, Вы писали:

H>Здравствуйте, RArthur, Вы писали:


H>Зачем тебе GCHandle? Почему бы не использовать блок fixed.


Привет,

Да и это просто пример, а на самом деле, в классе будут несколко вункций работающих с этими данными, не представляю как я смогу за-fixed эту коллекцию.
var data = new TickData[Program.Count]; (data — на самом деле будет мембером класса)

С Уважение Артур
Re[3]: Managed Unmanaged memory
От: fddima  
Дата: 12.07.13 08:51
Оценка:
Здравствуйте, RArthur, Вы писали:

RA>Да и это просто пример, а на самом деле, в классе будут несколко вункций работающих с этими данными, не представляю как я смогу за-fixed эту коллекцию.

RA>var data = new TickData[Program.Count]; (data — на самом деле будет мембером класса)
Это без разницы — покуда data — массив, его можно будет запинить.

    public class FixedUnsafeAllocate
    {
        [DllImport("NativeC.dll")]
        static unsafe extern int GetTick(TickData* data, int count);

        public unsafe void Execute()
        {
            var myData = new TickData[200];

            fixed (TickData* data = myData) // здесь пиниться весь массив
            {
                GetTick(data, myData.Length);
                // обрабатываем дальше
            }
        }
    }
Re[4]: Managed Unmanaged memory
От: RArthur  
Дата: 12.07.13 08:58
Оценка:
Здравствуйте, fddima, Вы писали:

F>Здравствуйте, RArthur, Вы писали:


RA>>Да и это просто пример, а на самом деле, в классе будут несколко вункций работающих с этими данными, не представляю как я смогу за-fixed эту коллекцию.

RA>>var data = new TickData[Program.Count]; (data — на самом деле будет мембером класса)
F> Это без разницы — покуда data — массив, его можно будет запинить.

F>
F>    public class FixedUnsafeAllocate
F>    {
F>        [DllImport("NativeC.dll")]
F>        static unsafe extern int GetTick(TickData* data, int count);

F>        public unsafe void Execute()
F>        {
F>            var myData = new TickData[200];

F>            fixed (TickData* data = myData) // здесь пиниться весь массив
F>            {
F>                GetTick(data, myData.Length);
F>                // обрабатываем дальше
F>            }
F>        }
F>    }
F>


Да, но как он только выйдет за fixed scope GC может его уже перемещать, а мне это не надо, так как данных очень много, а класс должен продолжать работать с этой областью памяти.

Спасибо,
Артур
Re[5]: Managed Unmanaged memory
От: hardcase Пират http://nemerle.org
Дата: 12.07.13 11:50
Оценка:
Здравствуйте, RArthur, Вы писали:

RA>Да, но как он только выйдет за fixed scope GC может его уже перемещать, а мне это не надо, так как данных очень много, а класс должен продолжать работать с этой областью памяти.


Если объект попадает в LOH, то GC его ни за какие коврижки не будет перемещать.
/* иЗвиНите зА неРовнЫй поЧерК */
Re[6]: Managed Unmanaged memory
От: fddima  
Дата: 12.07.13 11:57
Оценка: 3 (1) +1
Здравствуйте, hardcase, Вы писали:

RA>>Да, но как он только выйдет за fixed scope GC может его уже перемещать, а мне это не надо, так как данных очень много, а класс должен продолжать работать с этой областью памяти.

H>Если объект попадает в LOH, то GC его ни за какие коврижки не будет перемещать.
В 4.5.1 теперь будет. http://blogs.msdn.com/b/dotnet/archive/2013/06/26/announcing-the-net-framework-4-5-1-preview.aspx (On-demand large object heap compaction).
Re[3]: Managed Unmanaged memory
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 12.07.13 12:11
Оценка:
Здравствуйте, RArthur, Вы писали:

RA>Здравствуйте, hardcase, Вы писали:


H>>Здравствуйте, RArthur, Вы писали:


H>>Зачем тебе GCHandle? Почему бы не использовать блок fixed.


RA>Привет,


RA>Использую GCHandle чтоб GC не перемещал бы данные, объем которых слишком ольшой — около 10000000. Потому если GC переместит их, указатель в С++ уже не будет валидным.


RA>С Уважением

RA>Артур

Вообщето в Net два виида манагед куч. Для ЛОХов
Автор(ы): Чистяков Влад (VladD2)
Дата: 14.06.2006
Уже много сказано слов о том, что такое GC, чем он хорош и как лучше его применять. Но, наверно, очень многим хочется знать, как устроен конкретный GC. Данная статья открывает некоторые подробности устройчтва GC в .NET Framework.
отдельная и недефрагментируемая
Вот проверка
http://rsdn.ru/forum/design/701354
Автор: Serginio1
Дата: 30.06.04
и солнце б утром не вставало, когда бы не было меня
Re[4]: Managed Unmanaged memory
От: RArthur  
Дата: 12.07.13 12:27
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Здравствуйте, RArthur, Вы писали:


RA>>Здравствуйте, hardcase, Вы писали:


H>>>Здравствуйте, RArthur, Вы писали:


H>>>Зачем тебе GCHandle? Почему бы не использовать блок fixed.


RA>>Привет,


RA>>Использую GCHandle чтоб GC не перемещал бы данные, объем которых слишком ольшой — около 10000000. Потому если GC переместит их, указатель в С++ уже не будет валидным.


RA>>С Уважением

RA>>Артур

S> Вообщето в Net два виида манагед куч. Для ЛОХов
Автор(ы): Чистяков Влад (VladD2)
Дата: 14.06.2006
Уже много сказано слов о том, что такое GC, чем он хорош и как лучше его применять. Но, наверно, очень многим хочется знать, как устроен конкретный GC. Данная статья открывает некоторые подробности устройчтва GC в .NET Framework.
отдельная и недефрагментируемая

S> Вот проверка
S>http://rsdn.ru/forum/design/701354
Автор: Serginio1
Дата: 30.06.04


У меня может не обязательно быть 10000000 — может и 20, но во время работы все равно она не должна перемещаться или мы неправильно понимаем друг друга?
Re[5]: Managed Unmanaged memory
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 12.07.13 12:39
Оценка:
Здравствуйте, RArthur, Вы писали:


RA>У меня может не обязательно быть 10000000 — может и 20, но во время работы все равно она не должна перемещаться или мы неправильно понимаем друг друга?

Ну в свете http://blogs.msdn.com/b/dotnet/archive/2013/06/26/announcing-the-net-framework-4-5-1-preview.aspx
все же придется пинать и большие объекты
и солнце б утром не вставало, когда бы не было меня
Re[6]: Managed Unmanaged memory
От: RArthur  
Дата: 12.07.13 12:57
Оценка:
Здравствуйте, Serginio1, Вы писали:

S>Здравствуйте, RArthur, Вы писали:



RA>>У меня может не обязательно быть 10000000 — может и 20, но во время работы все равно она не должна перемещаться или мы неправильно понимаем друг друга?

S> Ну в свете http://blogs.msdn.com/b/dotnet/archive/2013/06/26/announcing-the-net-framework-4-5-1-preview.aspx
S>все же придется пинать и большие объекты
так что если я правильно понял придется оставить gchandle.alloc.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.