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();
}
}
}
Скажите пожалйста, могут ли быть проблемы и если да то где.
Здравствуйте, 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;
}
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, RArthur, Вы писали:
H>Зачем тебе GCHandle? Почему бы не использовать блок fixed.
Привет,
Использую GCHandle чтоб GC не перемещал бы данные, объем которых слишком ольшой — около 10000000. Потому если GC переместит их, указатель в С++ уже не будет валидным.
Здравствуйте, Sinix, Вы писали:
S>Здравствуйте, hardcase, Вы писали:
H>>Кстати, а чем не угодило так:
S>По памяти (могу ошибаться) можно совсем упростить жизнь (маршаллинг возьмёт на себя всю возню с fixed/unsafe): S>
Здравствуйте, hardcase, Вы писали:
H>Здравствуйте, RArthur, Вы писали:
H>Зачем тебе GCHandle? Почему бы не использовать блок fixed.
Привет,
Да и это просто пример, а на самом деле, в классе будут несколко вункций работающих с этими данными, не представляю как я смогу за-fixed эту коллекцию.
var data = new TickData[Program.Count]; (data — на самом деле будет мембером класса)
Здравствуйте, 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);
// обрабатываем дальше
}
}
}
Здравствуйте, 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 может его уже перемещать, а мне это не надо, так как данных очень много, а класс должен продолжать работать с этой областью памяти.
Здравствуйте, RArthur, Вы писали:
RA>Да, но как он только выйдет за fixed scope GC может его уже перемещать, а мне это не надо, так как данных очень много, а класс должен продолжать работать с этой областью памяти.
Если объект попадает в LOH, то GC его ни за какие коврижки не будет перемещать.
Здравствуйте, 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).
Здравствуйте, RArthur, Вы писали:
RA>Здравствуйте, hardcase, Вы писали:
H>>Здравствуйте, RArthur, Вы писали:
H>>Зачем тебе GCHandle? Почему бы не использовать блок fixed.
RA>Привет,
RA>Использую GCHandle чтоб GC не перемещал бы данные, объем которых слишком ольшой — около 10000000. Потому если GC переместит их, указатель в С++ уже не будет валидным.
RA>С Уважением RA>Артур
Здравствуйте, Serginio1, Вы писали:
S>Здравствуйте, RArthur, Вы писали:
RA>>Здравствуйте, hardcase, Вы писали:
H>>>Здравствуйте, RArthur, Вы писали:
H>>>Зачем тебе GCHandle? Почему бы не использовать блок fixed.
RA>>Привет,
RA>>Использую GCHandle чтоб GC не перемещал бы данные, объем которых слишком ольшой — около 10000000. Потому если GC переместит их, указатель в С++ уже не будет валидным.
RA>>С Уважением RA>>Артур
S> Вообщето в Net два виида манагед куч. Для ЛОХов
У меня может не обязательно быть 10000000 — может и 20, но во время работы все равно она не должна перемещаться или мы неправильно понимаем друг друга?