int64: асинхронно передать C# -> C++ -> C# через void*
От: Mr.Delphist  
Дата: 16.10.17 19:32
Оценка:
Коллеги, привет

Столкнулся с задачей:
  1. C# дёргает запрос в C++/CLI
  2. C++/CLI дергает сишную либу, у которой можно передать void* в качестве пользовательских данных
  3. сишная либа вызывает свой асинхронный код
  4. сишный асинхронный код дёргает callback, который через С++/CLI слушается в C# — туда можно пробросить этот void*, чтобы понимать, к какому запросу относится эта callback-нотификация

Был бы int — проблем нет, но тут int64, а билд всего этого безобразия в 32 bit и никак иначе (т.е. sizeof(void*) равен 4, апгрейд на 64 бита аппаратно невозможен). Как на ваш взгляд элегантней всего пробросить его через эту цепочку managed-unmanaged-managed?
Отредактировано 16.10.2017 19:46 Mr.Delphist . Предыдущая версия .
Re: int64: асинхронно передать C# -> C++ -> C# через void*
От: samius Япония http://sams-tricks.blogspot.com
Дата: 16.10.17 19:44
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

MD>Был бы int — проблем нет, но тут int64. Как на ваш взгляд элегантней всего пробросить его через эту цепочку managed-unmanaged-managed?

немного не понял, какого рода проблемы?
Обычно для этого используют
GCHandle.ToIntPtr(GCHandle.Alloc(@object))

Где @object — все что угодно в нашем AppDomain.
Re[2]: int64: асинхронно передать C# -> C++ -> C# через void
От: Mr.Delphist  
Дата: 16.10.17 20:22
Оценка:
Здравствуйте, samius, Вы писали:

S>
S>GCHandle.ToIntPtr(GCHandle.Alloc(@object))
S>

S>Где @object — все что угодно в нашем AppDomain.

Хотелось бы избежать ручного аллока, потому что цепочка асинхронная. В идеале — весь memory management остаётся в руках GC, unmanaged-код получает некий хэндл/индекс/etc., который потом виден в C#-колбэке. Повторюсь, у unmanaged API есть лишь 32-битный "void*" для user-defined param, в который и надо упихнуться нашим int64 за один раз.

И да, забыл упомянуть: unmanaged-код этим user-defined параметром никак не пользуется, кроме как подставляет в параметр асинхронного C#-колбэка.
Отредактировано 16.10.2017 20:32 Mr.Delphist . Предыдущая версия .
Re[3]: int64: асинхронно передать C# -> C++ -> C# через void*
От: samius Япония http://sams-tricks.blogspot.com
Дата: 16.10.17 20:47
Оценка:
Здравствуйте, Mr.Delphist, Вы писали:

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


S>>
S>>GCHandle.ToIntPtr(GCHandle.Alloc(@object))
S>>

S>>Где @object — все что угодно в нашем AppDomain.

MD>Хотелось бы избежать ручного аллока, потому что цепочка асинхронная.

Не понимаю, чем аллок может мешать асинхронной цепочке. Вообще, конечно, GCHandle это такой грязный пенек для GC, который ему все время придется обходить и при значительном кол-ве GCHandle, могу быть какие-то проблемы.

MD>В идеале — весь memory management остаётся в руках GC, unmanaged-код получает некий хэндл/индекс/etc., который потом виден в C#-колбэке. Повторюсь, у unmanaged API есть лишь 32-битный "void*" для user-defined param, в который и надо упихнуться нашим int64 за один раз.


Так это любой ассоциативный контейнер с ключем int плюс организация хранения свободных индексов.
Я для UserContext-ов использую список массивов фиксированной длины, который растет по необходимости и записывает свободные места в цепочку.
В тривиальном исполнении — комбинация Dictionary<int, T> и Stack<int>.
Re[4]: int64: асинхронно передать C# -> C++ -> C# через void*
От: Mr.Delphist  
Дата: 17.10.17 09:20
Оценка:
Здравствуйте, samius, Вы писали:

S>Так это любой ассоциативный контейнер с ключем int плюс организация хранения свободных индексов.

S>Я для UserContext-ов использую список массивов фиксированной длины, который растет по необходимости и записывает свободные места в цепочку.
S>В тривиальном исполнении — комбинация Dictionary<int, T> и Stack<int>.

Вот я как раз на подобном мэппинге пока и остановился, просто вдруг что-то есть более элегантное.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.