View mode: basic / threaded / horizontal-split · Log in · Help
May 30, 2012
Interfacing D to C R standalone math library
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
Re: Interfacing D to C R standalone math library
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
Re: Interfacing D to C R standalone math library
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
Re: Interfacing D to C R standalone math library
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
Re: Interfacing D to C R standalone math library
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
Re: Interfacing D to C R standalone math library
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
Re: Interfacing D to C R standalone math library
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
Top | Discussion index | About this forum | D home