ImportC and #include files

jmh530 john.michael.hall at gmail.com
Thu May 11 16:52:11 UTC 2023


On Monday, 8 May 2023 at 13:22:44 UTC, jmh530 wrote:
> [snip
> I was able to get nlopt's tutorial example working with 
> importC. I can write a bit more up later.
>

For some more details, in case anyone is interested (and myself 
in case I forget and need to search for it in the future). I 
installed nlopt as a shared library to some random location (I 
had to use cmake to disable installation of some parts, like how 
it handles python). I started with the tutorial [1] and put 
together a C version of the example and compiled with gcc using
```
gcc cversion.c -w -lnlopt -lm -L/usr/local/nlopt/nlopt/build/ 
-Wl,-rpath=/usr/local/nlopt/nlopt/build/ -o myprogram
```
The -Wl,rpath is because I didn't install the shared library into 
a usual location for shared libraries. How to actually do this in 
practice depends on how you install it and whether to use shared 
or static libraries. Regardless, I think it is good to get the C 
version working first.

I then created two .c files one that just includes nlopt.h and 
another that just includes math.h (as bachmeier recommends) and 
adjusted the C version of the tutorial to a D version (see below) 
and compiled with

```d
dmd dversion.d math.c nlopt.c -of=dversion -L-lnlopt 
-L--rpath=/usr/local/nlopt/nlopt/build/
```

dversion.d
```d
import math;
import nlopt;

extern(C)
double myfunc(uint n, const double* x, double* grad, void* 
my_func_data)
{
     if (grad) {
         grad[0] = 0.0;
         grad[1] = 0.5 / sqrt(x[1]);
     }
     return sqrt(x[1]);
}

struct my_constraint_data
{
     double a, b;
}

extern(C)
double myconstraint(uint n, const double* x, double* grad, void* 
data)
{
     my_constraint_data* d = cast(my_constraint_data*) data;
     double a = d.a, b = d.b;
     if (grad) {
         grad[0] = 3 * a * (a*x[0] + b) * (a*x[0] + b);
         grad[1] = -1.0;
     }
     return ((a*x[0] + b) * (a*x[0] + b) * (a*x[0] + b) - x[1]);
}

void main() {
     import core.stdc.stdio: printf;
     import core.stdc.math: HUGE_VAL;

     double[2] lb = [-HUGE_VAL, 0]; /* lower bounds */
     nlopt_opt opt;

     opt = nlopt_create(NLOPT_LD_MMA, 2); /* algorithm and 
dimensionality */
     nlopt_set_lower_bounds(opt, lb.ptr);
     nlopt_set_min_objective(opt, &myfunc, null);

     my_constraint_data[2] data = [{2,0}, {-1,1}];

     nlopt_add_inequality_constraint(opt, &myconstraint, &data[0], 
1e-8);
     nlopt_add_inequality_constraint(opt, &myconstraint, &data[1], 
1e-8);

     nlopt_set_xtol_rel(opt, 1e-4);

     double[2] x = [1.234, 5.678];  /* `*`some` `initial` 
`guess`*` */
     double minf = void; /* `*`the` `minimum` `objective` `value,` 
`upon` `return`*` */
     if (nlopt_optimize(opt, x.ptr, &minf) < 0) {
         printf("nlopt failed!\n");
     }
     else {
         printf("found minimum at f(%g,%g) = %0.10g\n", x[0], 
x[1], minf);
     }

     nlopt_destroy(opt);
}

```

[1] 
https://github.com/stevengj/nlopt/blob/master/doc/docs/NLopt_Tutorial.md


More information about the Digitalmars-d mailing list