Я не уверен, что он подходит, но возможно "Reverse PInvoke" - вариант.
Если вы можете сначала вызвать ваш C # на ваш C ++, то вы можете предоставить делегат .net на C ++, где он может использоваться в качестве указателя на функцию. Затем вы можете вызывать ваш C ++ в C #, используя этот указатель на функцию.
public delegate int Read(int target);
[DllImport("yourC++.dll")]
static extern void RegisterRead(Read x);
Read m_Read = new Read(yourClass.Read);
RegisterRead(m_Read);
Могут быть некоторые уловки с GC, собирающим делегата рано, любой класс, имеющий делегат, может нуждаться в закреплении, если он не используется сразу в RegisterRead