www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - D calling C?

reply Glenn Lewis <nospam nospam.net> writes:
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
Mar 03 2007
parent reply torhu <fake address.dude> writes:
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?
Mar 03 2007
parent reply Glenn Lewis <nospam nospam.net> writes:
 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?

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
Mar 03 2007
parent reply torhu <fake address.dude> writes:
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.
Mar 03 2007
parent Glenn Lewis <nospam nospam.net> writes:
== Quote from torhu's article
 A dynamic array in D consists of a length and a pointer.  So it's

 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
Mar 03 2007