www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - extremely subtle D --> C linking bug ... (dmd .139 linux)

reply clayasaurus <clayasaurus gmail.com> writes:
This bug was /almost/ a show stopper for me, just because it took so 
long to find it.

I attached two files, bug.d, and c_func.cpp.

Compile with..

g++ -c c_func.cpp
dmd bug.d c_func.o -L-lstdc++

The D version links to this function through

extern(C)
{
    void c_func(ushort a, ulong b, int c, ushort d);
}

and the actual function itself is

extern "C" {

    void c_func(unsigned short a, unsigned long b, int c, unsigned short d)
    {
       printf("%d %d %d %d\n", a, b, c, d);
    }

}

I call the function with the following arguments...

c_func(60000, 0, 0, 60000);

And it prints the following...

60000 0 0 0

It can be 'fixed' when you make all the arguments in the function the 
same type. I really have no clue why this is happening though.
Nov 15 2005
parent reply clayasaurus <clayasaurus gmail.com> writes:
clayasaurus wrote:
 This bug was /almost/ a show stopper for me, just because it took so 
 long to find it.
 
 I attached two files, bug.d, and c_func.cpp.
 
 Compile with..
 
 g++ -c c_func.cpp
 dmd bug.d c_func.o -L-lstdc++
 
 The D version links to this function through
 
 extern(C)
 {
    void c_func(ushort a, ulong b, int c, ushort d);
 }
 
 and the actual function itself is
 
 extern "C" {
 
    void c_func(unsigned short a, unsigned long b, int c, unsigned short d)
    {
       printf("%d %d %d %d\n", a, b, c, d);
    }
 
 }
 
 I call the function with the following arguments...
 
 c_func(60000, 0, 0, 60000);
 
 And it prints the following...
 
 60000 0 0 0
 
 It can be 'fixed' when you make all the arguments in the function the 
 same type. I really have no clue why this is happening though.
 
 
 
 
 
 
 
 
 ------------------------------------------------------------------------
 
 
 extern(C)
 {
    void c_func(ushort a, ulong b, int c, ushort d);
 }
 
 int main()
 {
    c_func(60000, 0, 0, 60000); 
 
    return 0;
 }
 
 
 ------------------------------------------------------------------------
 
 
 #include <stdio.h> 
 
 extern "C" {
 
    void c_func(unsigned short a, unsigned long b, int c, unsigned short d)
    {
       printf("%d %d %d %d\n", a, b, c, d);
    }
 
 }
Just found out it doesn't work if they are all ulong, but it does it they are all uint.
Nov 15 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
On Tue, 15 Nov 2005 11:04:18 -0500, clayasaurus <clayasaurus gmail.com>  
wrote:
 clayasaurus wrote:
 This bug was /almost/ a show stopper for me, just because it took so  
 long to find it.
  I attached two files, bug.d, and c_func.cpp.
  Compile with..
  g++ -c c_func.cpp
 dmd bug.d c_func.o -L-lstdc++
  The D version links to this function through
  extern(C)
 {
    void c_func(ushort a, ulong b, int c, ushort d);
 }
  and the actual function itself is
  extern "C" {
     void c_func(unsigned short a, unsigned long b, int c, unsigned  
 short d)
    {
       printf("%d %d %d %d\n", a, b, c, d);
    }
  }
  I call the function with the following arguments...
  c_func(60000, 0, 0, 60000);
  And it prints the following...
  60000 0 0 0
  It can be 'fixed' when you make all the arguments in the function the  
 same type. I really have no clue why this is happening though.
          
 ------------------------------------------------------------------------
   extern(C)
 {
    void c_func(ushort a, ulong b, int c, ushort d);
 }
  int main()
 {
    c_func(60000, 0, 0, 60000);     return 0;
 }
    
 ------------------------------------------------------------------------
   #include <stdio.h>  extern "C" {
     void c_func(unsigned short a, unsigned long b, int c, unsigned  
 short d)
    {
       printf("%d %d %d %d\n", a, b, c, d);
    }
  }
Just found out it doesn't work if they are all ulong, but it does it they are all uint.
A ulong in D is twice as long as an unsigned long in C (generally). For help converting C to D, see: http://www.digitalmars.com/d/type.html http://www.digitalmars.com/d/ctod.html#types In other words, if C says "unsigned long" in D you use "uint". eg. [original.c] void c_func(unsigned short a, unsigned long b, int c, unsigned short d) {} [your.d] extern(C) { void c_func(ushort a, uint b, int c, ushort d); } If however C used "long long" then you'd use D's "long" type. Regan
Nov 15 2005
parent reply clayasaurus <clayasaurus gmail.com> writes:
Regan Heath wrote:
 On Tue, 15 Nov 2005 11:04:18 -0500, clayasaurus <clayasaurus gmail.com>  
 wrote:
 
 clayasaurus wrote:

 This bug was /almost/ a show stopper for me, just because it took so  
 long to find it.
  I attached two files, bug.d, and c_func.cpp.
  Compile with..
  g++ -c c_func.cpp
 dmd bug.d c_func.o -L-lstdc++
  The D version links to this function through
  extern(C)
 {
    void c_func(ushort a, ulong b, int c, ushort d);
 }
  and the actual function itself is
  extern "C" {
     void c_func(unsigned short a, unsigned long b, int c, unsigned  
 short d)
    {
       printf("%d %d %d %d\n", a, b, c, d);
    }
  }
  I call the function with the following arguments...
  c_func(60000, 0, 0, 60000);
  And it prints the following...
  60000 0 0 0
  It can be 'fixed' when you make all the arguments in the function 
 the  same type. I really have no clue why this is happening though.
          
 ------------------------------------------------------------------------
   extern(C)
 {
    void c_func(ushort a, ulong b, int c, ushort d);
 }
  int main()
 {
    c_func(60000, 0, 0, 60000);     return 0;
 }
    
 ------------------------------------------------------------------------
   #include <stdio.h>  extern "C" {
     void c_func(unsigned short a, unsigned long b, int c, unsigned  
 short d)
    {
       printf("%d %d %d %d\n", a, b, c, d);
    }
  }
Just found out it doesn't work if they are all ulong, but it does it they are all uint.
A ulong in D is twice as long as an unsigned long in C (generally). For help converting C to D, see: http://www.digitalmars.com/d/type.html http://www.digitalmars.com/d/ctod.html#types
Thanks, I didn't realize that a unsigned long in C is the same as a uint in D.
 
 In other words, if C says "unsigned long" in D you use "uint". eg.
 
 [original.c]
 void c_func(unsigned short a, unsigned long b, int c, unsigned short d) {}
 
 [your.d]
 extern(C)
 {
   void c_func(ushort a, uint b, int c, ushort d);
 }
 
 If however C used "long long" then you'd use D's "long" type.
 
 Regan
 
Nov 15 2005
parent reply Mike Parker <aldacron71 yahoo.com> writes:
clayasaurus wrote:
  >
 Thanks, I didn't realize that a unsigned long in C is the same as a uint 
 in D.
 
Be careful with this, though. That's on 32-bit systems, where ints and longs are almost always the same size from compiler to compiler. On 64-bit systems, I have heard that some compilers treat longs as 64-bit and some do not. The C (and/or C++) spec does not specify anything other than 'a long is at least as big as an int'. When interfacing with C code, always be aware of the properties of the compiler you are using and the platform you are using it on.
Nov 15 2005
parent Thomas Kuehne <thomas-dloop kuehne.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Mike Parker schrieb am 2005-11-16:
 clayasaurus wrote:
  >
 Thanks, I didn't realize that a unsigned long in C is the same as a uint 
 in D.
 
Be careful with this, though. That's on 32-bit systems, where ints and longs are almost always the same size from compiler to compiler. On 64-bit systems, I have heard that some compilers treat longs as 64-bit and some do not. The C (and/or C++) spec does not specify anything other than 'a long is at least as big as an int'. When interfacing with C code, always be aware of the properties of the compiler you are using and the platform you are using it on.
for 64-bit systems: Microsoft - sizeof(int) == sizeof(long) most Posix systems - sizeof(int) * 2 == sizeof(long) And then there are options like GCC's -mlong32 and -mlong64 Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFDfoH93w+/yD4P9tIRAvDDAJwLXILVQA7wx97KO2jjlDNE+hDRiQCaAmpU lfIlwi4Lv2Ku7/Dz9wB8j2I= =F7Zy -----END PGP SIGNATURE-----
Nov 18 2005