www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Interfacing D to C R standalone math library

reply "TJB" <broughtj gmail.com> writes:
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 30 2012
next sibling parent reply Jacob Carlborg <doob me.com> writes:
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 30 2012
parent reply Mike Parker <aldacron gmail.com> writes:
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
parent Mike Parker <aldacron gmail.com> writes:
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
prev sibling next sibling parent "TJB" <broughtj gmail.com> writes:
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
prev sibling next sibling parent "TJB" <broughtj gmail.com> writes:
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
prev sibling parent "TJB" <broughtj gmail.com> writes:
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
May 31 2012