Одна проблема, которую я вижу здесь, состоит в том, что .Net имеет сборщик мусора, который может перемещать ваш класс. Таким образом, ваш сохраненный указатель может быть признан недействительным. Чтобы предотвратить это для простых типов, вы должны закрепить объект следующим образом:
byte[] b = new byte[1000];
// pin b, and get pointer to the first element.
fixed (byte* ptr = &b)
{
//use your fixed pointer to b. b will not be moved untill code leaves fixed region.
}
Хотя для сложных типов .Net может оказаться достаточно разумным для автоматического закрепления объектов, я бы на это не полагался.
Итак, вы должны написать что-то вроде этого:
var ctx = new Context();
fixed (IntPtr ptr = &ctx)
{
StatusChange(ptr);
// do other stuff, and don't leave fixed region, until you can clear the pointer in the native library.
}
Но на самом деле, я думаю, что гораздо более простым и надежным способом будет создание статического словаря для ваших контекстных объектов и предоставление вашей нативной dll только ключа для этого словаря, который может быть числом, строкой или GUID. Например. все, что является значением, а не указателем.