Thread overview
D calling C?
Mar 04, 2007
Glenn Lewis
Mar 04, 2007
torhu
Mar 04, 2007
Glenn Lewis
Mar 04, 2007
torhu
Mar 04, 2007
Glenn Lewis
March 04, 2007
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
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
> > 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
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
== 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