May 08, 2023

On Monday, 8 May 2023 at 15:50:09 UTC, jmh530 wrote:

>

On Monday, 8 May 2023 at 15:34:32 UTC, jmh530 wrote:

>

[snip]
I was assuming that importC would re-write that to an enum that I could use directly in the D file, but the spec says that it doesn't support all uses of metaprogramming with these. You think that's what I'm running into?

Hmm, I'm not sure how much sense that makes since I'm able to use it in the .c file...

To my knowledge, you're only able to use them in .c files. .d files aren't run through the preprocessor and I don't know of any way to access a C macro from D...but maybe I'm wrong. I've been using core.stdc.

May 08, 2023

On Monday, 8 May 2023 at 15:57:01 UTC, bachmeier wrote:

>

On Monday, 8 May 2023 at 15:50:09 UTC, jmh530 wrote:

>

On Monday, 8 May 2023 at 15:34:32 UTC, jmh530 wrote:

>

[snip]
I was assuming that importC would re-write that to an enum that I could use directly in the D file, but the spec says that it doesn't support all uses of metaprogramming with these. You think that's what I'm running into?

Hmm, I'm not sure how much sense that makes since I'm able to use it in the .c file...

To my knowledge, you're only able to use them in .c files. .d files aren't run through the preprocessor and I don't know of any way to access a C macro from D...but maybe I'm wrong. I've been using core.stdc.

If you have a simple #define in a .c file, you can access it from a .d file. I tried the importC spec example with #define COLOR 0x123456 getting re-written to enum COLOR = 0x123456; and it worked.

The HUGE_VAL macro is a little more complicated. It relies on #if and it calls some __builtin_huge_val. However, if I have static double LARGE_VAL = HUGE_VAL in the .c file, I was able to access LARGE_VAL in the .d file as expected. So the preprocessor is able to run, but maybe it's not creating the enum version due to the other macros going on.

May 08, 2023

On Monday, 8 May 2023 at 17:29:38 UTC, jmh530 wrote:

>

If you have a simple #define in a .c file, you can access it from a .d file. I tried the importC spec example with #define COLOR 0x123456 getting re-written to enum COLOR = 0x123456; and it worked.

That's useful to know. I was not aware.

>

The HUGE_VAL macro is a little more complicated. It relies on #if and it calls some __builtin_huge_val. However, if I have static double LARGE_VAL = HUGE_VAL in the .c file, I was able to access LARGE_VAL in the .d file as expected. So the preprocessor is able to run, but maybe it's not creating the enum version due to the other macros going on.

Looks like that's gcc:

https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005fhuge_005fval

Probably requires an addition to importc.h, as has been done for several other cases already:

https://github.com/dlang/dmd/blob/master/druntime/src/importc.h#L79

May 08, 2023

On Monday, 8 May 2023 at 17:54:45 UTC, bachmeier wrote:

>

On Monday, 8 May 2023 at 17:29:38 UTC, jmh530 wrote:

>

[...]

Looks like that's gcc:

https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html#index-_005f_005fbuiltin_005fhuge_005fval

Probably requires an addition to importc.h, as has been done for several other cases already:

https://github.com/dlang/dmd/blob/master/druntime/src/importc.h#L79

Something like below might be worth adding
#define __builtin_huge_val double.infinity
#define __builtin_huge_valf float.infinity
#define __builtin_huge_vall real.infinity
#define __builtin_inf double.infinity
#define __builtin_inff float.infinity
#define __builtin_infl real.infinity
#define __builtin_nan double.nan
#define __builtin_nanf float.nan
#define __builtin_nanl real.nan

DRuntime implements HUGE_VAL this way, though some reference materials say that it behaves differently on machines that don't have infinity defined. So it's a bit legacy.

Here's a potentially incomplete list of some things that would need to be defined to cover most of the rest of core.stdc.math:
FP_ILOGB0
FP_ILOGBNAN
__builtin_signbit
__builtin_fpclassify
__builtin_isfinite
__builtin_isnormal
__builtin_isgreaterequal
__builtin_isless
__builtin_islessequal
__builtin_islessgreater
__builtin_isunordered

May 08, 2023
Support for C macros being accessible to D code is very limited, pretty much just enums for constants.

I plan to improve this in the future, but it's what it is today.
May 08, 2023
On Monday, 8 May 2023 at 20:12:44 UTC, Walter Bright wrote:
> Support for C macros being accessible to D code is very limited, pretty much just enums for constants.
>
> I plan to improve this in the future, but it's what it is today.

Cool.

What I was reporting above was mostly due to these missing builtins. I think some of the simple ones with #if were working otherwise.
May 11, 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

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

dversion.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

May 12, 2023
On Thursday, 27 April 2023 at 20:16:32 UTC, Walter Bright wrote:
> Thanks! Every .h file we can make work makes ImportC that much more useful. It's a high leverage activity for time invested.

Just filed this one that seems to be a regression from the last major release: https://issues.dlang.org/show_bug.cgi?id=23913
May 12, 2023
Thank you, I'll check it out.
May 25, 2023

On Thursday, 27 April 2023 at 20:16:32 UTC, Walter Bright wrote:

>

Try using ImportC on various popular C .h files on your platform. For the ones that fail to compile, please find the offending few lines of code and post them to bugzilla.

ImportC for libuv (x64_windows):
https://forum.dlang.org/post/nztzlruptckjcplukpxl@forum.dlang.org

1 2 3 4
Next ›   Last »