In this final post, I will outline my attempts to "hide" the unsafe methods from the public C# interface and at the same time making the interface more object-oriented, for example to implicitly free the allocated resources in the IPOPT library when the optimization problem is completed.
The further developed C# interface can be found here. The implementation still contains privately declared unsafe code, so the code has to be compiled with the /unsafe flag enabled. However, if the code is included in a separate assembly, it should be possible to access the IPOPT C# interface from another assembly without having to enable the /unsafe flag.
To begin with, I need "safe" delegates representing the callback functions for objective, gradient, constraints evaluation etc. One example is given by the constraints evaluation delegate:
public delegate bool EvaluateConstraintsDelegate(int n, double x, bool new_x, int m, double g);
This is similar to the original Eval_G_CB delegate (which has now been declared private, in the spirit of hiding the unsafe code):
unsafe private delegate int Eval_G_CB(int n, double* x, int new_x, int m, double* g, void* user_data);
The return value and the new_x variable are in practice Boolean, therefore they are declared as such in the "safe" delegate. The pointers into arrays, x and g, are in the "safe" delegate declared as arrays. Finally, user_data is considered redundant in the "safe" delegate, since the state of the optimization problem can suitably be represented within a class that holds implementations of the objective, constraints, gradient functions etc. in C#.
I never managed to finish this post in conjunction with the other two posts.