On Wednesday, 20 June 2018 at 18:47:10 UTC, Jordi GutiƩrrez Hermoso wrote:

Another possibility might be in dlopen'able functions. Currently Octave uses so-called oct functions, which are nothing more than C++ object code that is dynamically loaded by the interpreter at runtime. They are compiled to the Octave C++ API, but we also have a Matlab-compatible C API that perhaps could be more amenable for D-ification.

Can confirm that dpp works to create mex files. Rewriting the mypow2.c example in D:

File mypow3.dpp

#include "mex.h"
import std.conv, std.stdio;

extern(C) void mexFunction(int nlhs, mxArray** plhs,
             int nrhs, const mxArray** prhs) {
  mwSize n;
  mwIndex i;
  double * vri;
  double * vro;

  if (nrhs != 1 || !mxIsDouble(prhs[0]))
    mexErrMsgTxt ("ARG1 must be a double matrix");

  n = mxGetNumberOfElements(prhs[0]).to!int;
plhs[0] = mxCreateNumericArray (mxGetNumberOfDimensions (prhs[0]),
                                  mxGetDimensions (prhs[0]),
                                  mxGetClassID (prhs[0]),
mxIsComplex(prhs[0]).to!mxComplexity);
  vri = mxGetPr (prhs[0]);
  vro = mxGetPr (plhs[0]);

  if (mxIsComplex (prhs[0])) {
      double* vii, vio;
      vii = mxGetPi (prhs[0]);
      vio = mxGetPi (plhs[0]);

      for (i = 0; i < n; i++)
        {
          vro[i] = vri[i] * vri[i] - vii[i] * vii[i];
          vio[i] = 2 * vri[i] * vii[i];
        }
  } else {
      for (i = 0; i < n; i++)
        vro[i] = vri[i] * vri[i];
    }
}

Create the shared library using the information provided by mkoctfile:

d++ -c -fPIC --include-path /usr/include/octave-4.2.2/octave/.. \
--include-path /usr/include/octave-4.2.2/octave \
--include-path /usr/include/hdf5/serial mypow3.dpp

dmd -shared -defaultlib=libphobos2.so -of=mypow3.mex mypow3.o \
-L/usr/lib/x86_64-linux-gnu/liboctinterp.so \
-L/usr/lib/x86_64-linux-gnu/liboctave.so


In Octave:

b = randn (4,1);
mypow3(b)
ans =

   0.45984
   3.54732
   0.30075
   2.09107



Reply via email to