View mode: basic / threaded / horizontal-split · Log in · Help
March 04, 2007
D calling C?
Hi!  I'm trying to write a D program that calls C.
I've attached two listings: t1.d and t2.cpp.
Here's what happens:

C:\tmp>dmd -c t1.d
C:\tmp>dmc -c t2.cpp
C:\tmp>dmd -oft1.exe t1.obj t2.obj
C:\dmd\bin\..\..\dm\bin\link.exe t1+t2,t1.exe,,user32+kernel32/noi;
C:\tmp>t1
Error: Access Violation

I'm using DMD version 1.006 and DMC version 8.42n on WinXP.
Anyone have any ideas why this doesn't work?
Thanks!
-- Glenn Lewis
March 04, 2007
Re: D calling C?
Glenn Lewis wrote:
> Hi!  I'm trying to write a D program that calls C.
> I've attached two listings: t1.d and t2.cpp.
> Here's what happens:
> 
> C:\tmp>dmd -c t1.d
> C:\tmp>dmc -c t2.cpp
> C:\tmp>dmd -oft1.exe t1.obj t2.obj
> C:\dmd\bin\..\..\dm\bin\link.exe t1+t2,t1.exe,,user32+kernel32/noi;
> C:\tmp>t1
> Error: Access Violation
> 
> I'm using DMD version 1.006 and DMC version 8.42n on WinXP.
> Anyone have any ideas why this doesn't work?

The attachments are not understood by thunderbird, they are just shown 
inline in some kind of unreadable encoding.  Maybe you could just paste 
the sources into the message?
March 04, 2007
Re: D calling C?
> > Hi!  I'm trying to write a D program that calls C.
> > I've attached two listings: t1.d and t2.cpp.
> > Here's what happens:
> >
> > C:\tmp>dmd -c t1.d
> > C:\tmp>dmc -c t2.cpp
> > C:\tmp>dmd -oft1.exe t1.obj t2.obj
> > C:\dmd\bin\..\..\dm\bin\link.exe t1+t2,t1.exe,,user32+kernel32/noi;
> > C:\tmp>t1
> > Error: Access Violation
> >
> > I'm using DMD version 1.006 and DMC version 8.42n on WinXP.
> > Anyone have any ideas why this doesn't work?
> The attachments are not understood by thunderbird, they are just shown
> inline in some kind of unreadable encoding.  Maybe you could just paste
> the sources into the message?

Oh, sorry.  Here they are:
---------------------------------------
// t1.d
import std.stdio;

extern (C) { float func(float v[]); }

void main(char[][] argv)
{
 float v[2];
 v[0] = 0.0;
 v[1] = 1.0;
 float x = func(v);
 writefln("x=%g", x);
}
------------------------------------------
// t2.cpp
#include <stdio.h>

extern "C" { float func(float* v); }

float func(float v[])
{
 printf("v[0]=%g, v[1]=%g", v[0], v[1]);
 return v[0] + v[1];
}
--------------------------------------------
-- Glenn
March 04, 2007
Re: D calling C?
Glenn Lewis wrote:
> Oh, sorry.  Here they are:
> ---------------------------------------
> // t1.d
> import std.stdio;
> 
> extern (C) { float func(float v[]); }
> 
> void main(char[][] argv)
> {
>   float v[2];
>   v[0] = 0.0;
>   v[1] = 1.0;
>   float x = func(v);
>   writefln("x=%g", x);
> }
> ------------------------------------------
> // t2.cpp
> #include <stdio.h>
> 
> extern "C" { float func(float* v); }
> 
> float func(float v[])
> {
>   printf("v[0]=%g, v[1]=%g", v[0], v[1]);
>   return v[0] + v[1];
> }
> --------------------------------------------
> -- Glenn

A dynamic array in D consists of a length and a pointer.  So it's not 
binary compatible with a pointer.  A static array works, though.  If the 
length is fixed at two, you can do this:

extern (C) float func(float v[2]);
float x = func(v);


Or just use a pointer:

extern (C) float func(float* v);
float x = func(v.ptr);


Or have the length as an arg:

extern (C) float func(float* v, size_t n);
float x = func(v.ptr, v.len);


If the C function takes the length first, then the pointer, this also works:

extern (C) float func(float[] v);
float x = func(v);


The last one is a bit ugly, since it depends on the actual layout of 
dynamic array references.  Not that that's likely to change.
March 04, 2007
Re: D calling C?
== Quote from torhu's article
> A dynamic array in D consists of a length and a pointer.  So it's
not
> binary compatible with a pointer.  A static array works, though.

Ah!  I thought that was only a property of D strings!
Thank you very much!
I really appreciate it!
-- Glenn Lewis
Top | Discussion index | About this forum | D home