public Sudoku(SudokuReadData readFunc, SudokuWriteData writeFunc, SolveProcessCallback procCallback) { if (readFunc == null || writeFunc == null) { throw new Exception("read function and write function should not be null!"); } IntPtr readPtr = Marshal.GetFunctionPointerForDelegate(new SudokuLib.SudokuReadData((IntPtr data, int row, int col) => { return(readFunc.Invoke(row, col)); })); IntPtr writePtr = Marshal.GetFunctionPointerForDelegate(new SudokuLib.SudokuWriteData((IntPtr data, int row, int col, int value, int type) => { writeFunc.Invoke(row, col, value, (SolveType)type); })); IntPtr solvePtr = Marshal.GetFunctionPointerForDelegate(new SudokuLib.SolveProcessCallback((IntPtr data, IntPtr proc) => { if (procCallback == null) { return; } SolveProcedure procedure = (SolveProcedure)Marshal.PtrToStructure(proc, typeof(SolveProcedure)); procCallback.Invoke(procedure); })); sudo = SudokuLib.CreateSudoku(readPtr, writePtr, solvePtr, IntPtr.Zero); }