Introduction
The best way to get started using the wrapper is to open up the example projects included with this package and experiment with them. The auto-completion feature in Visual Studio can be used to obtain a full list of class methods and properties and prototypes of each method.
The Optimizer .NET interface targets .NET Framework 3.5 and .NET Standard 2.0 and can be used with a .NET version supporting either on Windows, but only .NET Standard 2.0 and greater are supported on Linux.
The Optimizer functionality is exposed through the XPRS and XPRSprob classes, which reside in the Optimizer namespace, which resides in the FICO.Xpress.XPRSdn package or the xprsdn.dll assembly. Each source file that uses the Optimizer should import the Optimizer namespace and should be compiled with a reference to FICO.Xpress.XPRSdn.
The Xpress .NET interfaces are distributed as NuGet packages in the xpressmp/lib/nuget folder. If using Visual Studio, you can add this folder as a NuGet package source by performing the following steps:
Click on NuGet Package Manager > Package Manager Settings in the Tools menu.
Select Package Sources.
Click the + icon to add a new source, then name it "Xpress local packages".
Select the folder C:\xpressmp\lib\nuget
Click Update.
Ensure the box to the left of "Xpress local packages" in the package sources list is checked.
Click OK to save the changes.
To add the wrapper to a Visual Studio project:
Select Manage NuGet Packages from the Project menu.
Select Xpress local packages from the Package source drop-down in the upper right, then select FICO.Xpress.XPRSdn from the Browse tab, and click Install to add it to the project.
If you are using the .NET CLI, use the following command to add xprsdn to your project:
dotnet add package -s C:\xpressmp\lib\nuget FICO.Xpress.XPRSdn
In all cases, the wrapper does not include the Xpress Solver and a local installation of Xpress will be required to use the wrapper library.
The Xpress installations for Windows include a .NET Framework 3.5-targeted assembly xpressmp/bin/xprsdn.dll for legacy reasons; new applications should not reference this file and existing projects should migrate to referencing the NuGet package instead.
The .NET wrapper for the Xpress Optimizer has been designed to look and feel like the Common Language Runtime. Compare code using the existing C Optimizer interface with the following C# example:
using Optimizer; XPRS.Init(""); Console.WriteLine(XPRS.GetBanner()); XPRSprob prob = new XPRSprob(); prob.ReadProb("myprob",""); prob.Maxim("g"); prob.Dispose(); XPRS.Free();
The Optimizer functions have been renamed and put into classes. The function name is missing the XPRS prefix, and according to the .NET naming convention, each word is capitalized. Functions operating on a problem pointer are methods of an XPRSprob object; the rest are static methods of the XPRS class.
The Optimizer controls and attributes are properties of the XPRSprob object.
They have been renamed in a similar way to the functions:
prob.Presolve = 0;
Some attributes such as MIPStatus and LPStatus are no longer integers but have enumeration types, e.g. MIPStatus and LPStatus:
if (prob.MIPStatus == MIPStatus.Infeasible) {
...
The Optimizer callbacks are accessed by registering appropriate delegates.
For example, to install a method OptimizerMsg of the current class as a callback to receive Optimizer messages, you can create a MessageCallback delegate object from the function and add it to the problem:
prob.AddMessageCallback(this.OptimizerMsg);
To remove a callback you use a function like RemoveMessageCallback.
An example of defining a message callback method, as demonstrated in the FICO Xpress Optimization Examples Repository:
public void OptimizerMsg (XPRSprob prob, object data, string message, int len, int msglvl) { switch(msglvl) { case 3: case 4: Console.WriteLine ("{0}: {1}", data, message); break; } }
Most of the functions in the C interface to the Optimizer use an integer return code to indicate if an error occurred.
The XPRS and XPRSprob member functions instead use the .NET exception mechanism to handle errors, throwing an exception of type XPRSException. This makes error handling easier, since a check is not required with every function call:
try { XPRS.Init(""); Console.WriteLine(XPRS.GetBanner()); XPRSprob prob = new XPRSprob(); prob.ReadProb("myprob",""); prob.MipOptimize("g"); } catch (XPRSException e) { Console.WriteLine (e); }
Because the return code is not used to indicate error status, several methods instead return data that in the C interface is returned via an output parameter. In general, a function that retrieves a single value returns it, whereas a function that retrieves more than one value is declared void and uses output parameters. For example:
/* In C# */ try { string name = prob.GetProbName (); } catch (XPRSException e) {
/* In C */ char name[32]; int ret = XPRSgetprobname (name); if (ret != 0) {
.NET uses a garbage collector, and it will eventually destroy unreferenced objects.
Optimizer problems can take up large amounts of memory and so a Dispose function is provided to immediately free up this memory. Any operation performed on an XPRSprob object after it has been disposed will throw an exception.
XPRSprob prob = new XPRSprob ();
...
prob.Dispose ();
© 2001-2025 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.