В CI есть функция, которая регистрирует обратный вызов и объект состояния, а затем передает объект состояния в обратный вызов каждый раз, когда он вызывается, так же, как EventHandler<EventArgs>
работает в C #.У меня есть класс в C #, который регистрирует управляемый обратный вызов с помощью функции C и в настоящее время передает IntPtr.Zero
, и я просто не использую его, потому что я не нашел хорошего и чистого способа передачи ссылки на управляемый объект в C и получения его обратнов C #.
Я не хочу, чтобы управляемый объект был доступен в C, я просто хочу передать его в C и передать его (дословно) в управляемый обратный вызов каждый раз, когда он вызывается из C.
В общем, ищем "правильный" способ сделать это.
Вот мой делегат для вызова:
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.SysInt)]
internal delegate IntPtr LuaAllocator(
[In, MarshalAs(UnmanagedType.AsAny)] object args,
[In, MarshalAs(UnmanagedType.SysInt)] IntPtr ptr,
[In, MarshalAs(UnmanagedType.SysInt)] IntPtr originalSize,
[In, MarshalAs(UnmanagedType.SysInt)] IntPtr newSize);
Вот текущий DllImport
Iя делаю:
[DllImport(DllName, EntryPoint = "lua_newstate", ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.SysInt)]
public static extern IntPtr NewState(
[In, MarshalAs(UnmanagedType.FunctionPtr)] LuaAllocator allocator,
[In, MarshalAs(UnmanagedType.AsAny)] object args);
И ошибка, которую я получаю прямо сейчас:
MarshalDirectiveException не обработан: Cannot marshal 'параметр # 1': AsAny не может быть использован навозвращаемые типы, параметры ByRef, ArrayWithOffset или параметры, передаваемые из неуправляемого в управляемое.
Эта ошибка исчезает, если я оставляю первый аргумент делегата как IntPtr
и использую MarshalAs.SysInt
, но тогда я не могуЯ не могу восстановить управляемый объект, но я получаю значение, отличное от IntPtr.Zero
, что любопытно и может оказаться полезным.