Thread overview
Interfacing D to C R standalone math library
May 30, 2012
TJB
May 31, 2012
Jacob Carlborg
May 31, 2012
TJB
May 31, 2012
TJB
May 31, 2012
Mike Parker
May 31, 2012
Mike Parker
May 31, 2012
TJB
May 30, 2012
Hello!

I am still wet behind the ears with D.  I am trying to interface to an existing C library from the R standalone math library (www.r-project.org).  I can call the library quite easily from a C++ program as follows:


#include <iostream>
#include <time.h>
#define MATHLIB_STANDALONE
#include "Rmath.h"

using namespace std;

int main() {
  int i, n;
  double sum, x;
  time_t tt;

  tt = time(NULL);

  set_seed(tt, 77911);

  cout << "How many random normals to find the mean? ";
  cin >> n;

  sum = 0.0;
  for(i = 0; i < n; i++) {
    sum += rnorm(0, 1);
  }

  cout << "mean is " << sum/n << endl;

  return 0;
}

I can compile this with:

$ g++ -o rnorm rnorm.cpp -I /usr/include -L /usr/lib -lRmath -lm

When I grep rnorm from the Rmath.h header file I get:

$ grep rnorm Rmath.h
#define rnorm		Rf_rnorm
double	rnorm(double, double);

I have written D code to call this as follows:

import std.stdio;

extern (C) double rnorm(double, double);

void main() {
  writeln(myfunc(0.0, 1.0));
}

double myfunc(double a, double b) {
  return rnorm(a, b);
}

But I don't know what I need to do to compile it.  What flags do I add? What else do I have to do?

Thanks for your help!


May 31, 2012
On 2012-05-30 21:20, TJB wrote:
> Hello!
>
> I am still wet behind the ears with D. I am trying to interface to an
> existing C library from the R standalone math library
> (www.r-project.org). I can call the library quite easily from a C++
> program as follows:
>
>
> #include <iostream>
> #include <time.h>
> #define MATHLIB_STANDALONE
> #include "Rmath.h"
>
> using namespace std;
>
> int main() {
> int i, n;
> double sum, x;
> time_t tt;
>
> tt = time(NULL);
>
> set_seed(tt, 77911);
>
> cout << "How many random normals to find the mean? ";
> cin >> n;
>
> sum = 0.0;
> for(i = 0; i < n; i++) {
> sum += rnorm(0, 1);
> }
>
> cout << "mean is " << sum/n << endl;
>
> return 0;
> }
>
> I can compile this with:
>
> $ g++ -o rnorm rnorm.cpp -I /usr/include -L /usr/lib -lRmath -lm
>
> When I grep rnorm from the Rmath.h header file I get:
>
> $ grep rnorm Rmath.h
> #define rnorm Rf_rnorm
> double rnorm(double, double);
>
> I have written D code to call this as follows:
>
> import std.stdio;
>
> extern (C) double rnorm(double, double);
>
> void main() {
> writeln(myfunc(0.0, 1.0));
> }
>
> double myfunc(double a, double b) {
> return rnorm(a, b);
> }
>
> But I don't know what I need to do to compile it. What flags do I add?
> What else do I have to do?
>
> Thanks for your help!
>
>

You just need to link to the external libraries.

$ dmd rnorm.d -L-L/usr/lib -L-lRmath -L-lm

-- 
/Jacob Carlborg
May 31, 2012
Jacob,

Yep!  That did it. Thank you very much!

TJB

On Thursday, 31 May 2012 at 06:19:34 UTC, Jacob Carlborg wrote:
> On 2012-05-30 21:20, TJB wrote:
>> Hello!
>>
>> I am still wet behind the ears with D. I am trying to interface to an
>> existing C library from the R standalone math library
>> (www.r-project.org). I can call the library quite easily from a C++
>> program as follows:
>>
>>
>> #include <iostream>
>> #include <time.h>
>> #define MATHLIB_STANDALONE
>> #include "Rmath.h"
>>
>> using namespace std;
>>
>> int main() {
>> int i, n;
>> double sum, x;
>> time_t tt;
>>
>> tt = time(NULL);
>>
>> set_seed(tt, 77911);
>>
>> cout << "How many random normals to find the mean? ";
>> cin >> n;
>>
>> sum = 0.0;
>> for(i = 0; i < n; i++) {
>> sum += rnorm(0, 1);
>> }
>>
>> cout << "mean is " << sum/n << endl;
>>
>> return 0;
>> }
>>
>> I can compile this with:
>>
>> $ g++ -o rnorm rnorm.cpp -I /usr/include -L /usr/lib -lRmath -lm
>>
>> When I grep rnorm from the Rmath.h header file I get:
>>
>> $ grep rnorm Rmath.h
>> #define rnorm Rf_rnorm
>> double rnorm(double, double);
>>
>> I have written D code to call this as follows:
>>
>> import std.stdio;
>>
>> extern (C) double rnorm(double, double);
>>
>> void main() {
>> writeln(myfunc(0.0, 1.0));
>> }
>>
>> double myfunc(double a, double b) {
>> return rnorm(a, b);
>> }
>>
>> But I don't know what I need to do to compile it. What flags do I add?
>> What else do I have to do?
>>
>> Thanks for your help!
>>
>>
>
> You just need to link to the external libraries.
>
> $ dmd rnorm.d -L-L/usr/lib -L-lRmath -L-lm


May 31, 2012
One more question, if I may.  I noticed that I forgot to include the set_seed function.  The call to rnorm works the way I have called it, but it must be using some default seed (its a random number generator).

I have tried including the set_seed function as follows:

import std.stdio;

extern (C) void set_seed(unsigned int, unsigned int);
extern (C) double rnorm(double, double);

void main() {
  set_seed(0,77991);
  foreach(i; 0 .. 100) {
    writeln(myfunc(0.0, 1.0));
  }
}

double myfunc(double a, double b) {
  return rnorm(a, b);
}

I compile this the same way as you suggest, but now the compiler is squealing at me with the following message:

$ dmd rnorm.d -L-L/usr/lob -L-lRmath -L-lm
rnorm.d(6): found 'int' when expecting ')'
rnorm.d(6): semicolon expected following function declaration
rnorm.d(6): Declaration expected, not ','

When I grep set_seed in Rmath.h I get:

$ grep set_seed Rmath.h
void	set_seed(unsigned int, unsigned int);

So I think I have called it correctly. Any thoughts or suggestions?

Thanks, you have been so helpful!

TJB


May 31, 2012
On 5/31/2012 9:40 PM, TJB wrote:
> One more question, if I may. I noticed that I forgot to include the
> set_seed function. The call to rnorm works the way I have called it, but
> it must be using some default seed (its a random number generator).
>
> I have tried including the set_seed function as follows:
>
> import std.stdio;
>
> extern (C) void set_seed(unsigned int, unsigned int);
> extern (C) double rnorm(double, double);
>
> void main() {
> set_seed(0,77991);
> foreach(i; 0 .. 100) {
> writeln(myfunc(0.0, 1.0));
> }
> }
>
> double myfunc(double a, double b) {
> return rnorm(a, b);
> }
>
> I compile this the same way as you suggest, but now the compiler is
> squealing at me with the following message:
>
> $ dmd rnorm.d -L-L/usr/lob -L-lRmath -L-lm
> rnorm.d(6): found 'int' when expecting ')'
> rnorm.d(6): semicolon expected following function declaration
> rnorm.d(6): Declaration expected, not ','
>
> When I grep set_seed in Rmath.h I get:
>
> $ grep set_seed Rmath.h
> void set_seed(unsigned int, unsigned int);
>
> So I think I have called it correctly. Any thoughts or suggestions?
>
> Thanks, you have been so helpful!
>
> TJB
>
>

D doesn't know anything about C's 'unsigned int'. You need to convert parameters to the equivalent in D, which would be uint.

 extern (C) void set_seed(unsigned int, unsigned int);

See the following page for more info on interfacing with C:

http://dlang.org/interfaceToC.html
May 31, 2012
On 5/31/2012 9:51 PM, Mike Parker wrote:
> On 5/31/2012 9:40 PM, TJB wrote:
>> One more question, if I may. I noticed that I forgot to include the
>> set_seed function. The call to rnorm works the way I have called it, but
>> it must be using some default seed (its a random number generator).
>>
>> I have tried including the set_seed function as follows:
>>
>> import std.stdio;
>>
>> extern (C) void set_seed(unsigned int, unsigned int);
>> extern (C) double rnorm(double, double);
>>
>> void main() {
>> set_seed(0,77991);
>> foreach(i; 0 .. 100) {
>> writeln(myfunc(0.0, 1.0));
>> }
>> }
>>
>> double myfunc(double a, double b) {
>> return rnorm(a, b);
>> }
>>
>> I compile this the same way as you suggest, but now the compiler is
>> squealing at me with the following message:
>>
>> $ dmd rnorm.d -L-L/usr/lob -L-lRmath -L-lm
>> rnorm.d(6): found 'int' when expecting ')'
>> rnorm.d(6): semicolon expected following function declaration
>> rnorm.d(6): Declaration expected, not ','
>>
>> When I grep set_seed in Rmath.h I get:
>>
>> $ grep set_seed Rmath.h
>> void set_seed(unsigned int, unsigned int);
>>
>> So I think I have called it correctly. Any thoughts or suggestions?
>>
>> Thanks, you have been so helpful!
>>
>> TJB
>>
>>
>
> D doesn't know anything about C's 'unsigned int'. You need to convert
> parameters to the equivalent in D, which would be uint.
>
> extern (C) void set_seed(unsigned int, unsigned int);
>
> See the following page for more info on interfacing with C:
>
> http://dlang.org/interfaceToC.html

Sorry, I meant:

 extern (C) void set_seed(uint, uint);

May 31, 2012
On Thursday, 31 May 2012 at 12:52:15 UTC, Mike Parker wrote:
> On 5/31/2012 9:51 PM, Mike Parker wrote:
>> On 5/31/2012 9:40 PM, TJB wrote:
>>> One more question, if I may. I noticed that I forgot to include the
>>> set_seed function. The call to rnorm works the way I have called it, but
>>> it must be using some default seed (its a random number generator).
>>>
>>> I have tried including the set_seed function as follows:
>>>
>>> import std.stdio;
>>>
>>> extern (C) void set_seed(unsigned int, unsigned int);
>>> extern (C) double rnorm(double, double);
>>>
>>> void main() {
>>> set_seed(0,77991);
>>> foreach(i; 0 .. 100) {
>>> writeln(myfunc(0.0, 1.0));
>>> }
>>> }
>>>
>>> double myfunc(double a, double b) {
>>> return rnorm(a, b);
>>> }
>>>
>>> I compile this the same way as you suggest, but now the compiler is
>>> squealing at me with the following message:
>>>
>>> $ dmd rnorm.d -L-L/usr/lob -L-lRmath -L-lm
>>> rnorm.d(6): found 'int' when expecting ')'
>>> rnorm.d(6): semicolon expected following function declaration
>>> rnorm.d(6): Declaration expected, not ','
>>>
>>> When I grep set_seed in Rmath.h I get:
>>>
>>> $ grep set_seed Rmath.h
>>> void set_seed(unsigned int, unsigned int);
>>>
>>> So I think I have called it correctly. Any thoughts or suggestions?
>>>
>>> Thanks, you have been so helpful!
>>>
>>> TJB
>>>
>>>
>>
>> D doesn't know anything about C's 'unsigned int'. You need to convert
>> parameters to the equivalent in D, which would be uint.
>>
>> extern (C) void set_seed(unsigned int, unsigned int);
>>
>> See the following page for more info on interfacing with C:
>>
>> http://dlang.org/interfaceToC.html
>
> Sorry, I meant:
>
>  extern (C) void set_seed(uint, uint);

Ah, yes.  That works!  Thank you.

I'm loving D programming and its community.  I can see myself never using C++ again.

TJB