www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - cast a C char array - offset ?

reply "irtcupc" <irtcupc nowhere.fi> writes:
The manual section about interfacing from c states that "type[]" 
is inter-compatible from C to D,

however, I face this strange case:

- C declaration:
char identifier[64];

- D declaration:
char[64] identifier;

- the result is only correct if i slice by (- pointer size):
char[64] fromC(char[64] * thing)
{
     const offs = size_t.sizeof;
     return thing[-offs.sizeof .. $-offs];
}

Is this correct ?
Feb 02 2015
next sibling parent reply FG <home fgda.pl> writes:
On 2015-02-02 at 13:16, irtcupc wrote:
 The manual section about interfacing from c states that "type[]" is
inter-compatible from C to D,

 however, I face this strange case:

 - C declaration:
 char identifier[64];

 - D declaration:
 char[64] identifier;

 - the result is only correct if i slice by (- pointer size):
 char[64] fromC(char[64] * thing)
 {
      const offs = size_t.sizeof;
      return thing[-offs.sizeof .. $-offs];
 }

 Is this correct ?
So you have to shift the whole array right by 4 or 8 bytes? Strange. Looks like an alignment issue. Is identifier part of a bigger structure?
Feb 02 2015
parent reply "irtcupc" <irtcupc nowhere.fi> writes:
On Monday, 2 February 2015 at 12:42:24 UTC, FG wrote:
 On 2015-02-02 at 13:16, irtcupc wrote:
 The manual section about interfacing from c states that 
 "type[]" is inter-compatible from C to D,

 however, I face this strange case:

 - C declaration:
 char identifier[64];

 - D declaration:
 char[64] identifier;

 - the result is only correct if i slice by (- pointer size):
 char[64] fromC(char[64] * thing)
 {
     const offs = size_t.sizeof;
     return thing[-offs.sizeof .. $-offs];
 }

 Is this correct ?
So you have to shift the whole array right by 4 or 8 bytes? Strange. Looks like an alignment issue. Is identifier part of a bigger structure?
Yes: C struct: #pragma pack(1) typedef struct _Disasm { UIntPtr EIP; UInt64 VirtualAddr; UInt32 SecurityBlock; char CompleteInstr[INSTRUCT_LENGTH]; UInt32 Archi; UInt64 Options; INSTRTYPE Instruction; ARGTYPE Argument1; ARGTYPE Argument2; ARGTYPE Argument3; PREFIXINFO Prefix; InternalDatas Reserved_; } DISASM, *PDISASM, *LPDISASM; #pragma pack() D struct: align(1) struct _Disasm { void * EIP; ulong VirtualAddr; uint SecurityBlock; char [INSTRUCT_LENGTH] CompleteInstr; uint Archi; ulong Options; INSTRTYPE Instruction; ARGTYPE Argument1; ARGTYPE Argument2; ARGTYPE Argument3; PREFIXINFO Prefix; uint Reserved_[40]; } my current understanding is that: - C: char CompleteInstr[INSTRUCT_LENGTH] is actually a raw chunk - D: defining the member as char[INSTRUCT_LENGTH] is an error - the first member of a D array is the .length - first char actually stands where .length uses to be, which explains the shift. - I cant use fromStringz because it's not a null terminated string
Feb 02 2015
parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Mon, 02 Feb 2015 13:23:23 +0000, irtcupc wrote:

 my current understanding is that:
 - C: char CompleteInstr[INSTRUCT_LENGTH] is actually a raw chunk - D:
 defining the member as char[INSTRUCT_LENGTH] is an error - the first
 member of a D array is the .length - first char actually stands where
 .length uses to be, which explains the shift.
nope. fixed length arrays doesn't have dedicated `.length` member. try=20 this: align(1) struct _Disasm { align(1): ... =
Feb 02 2015
parent reply ketmar <ketmar ketmar.no-ip.org> writes:
On Mon, 02 Feb 2015 13:32:57 +0000, ketmar wrote:

 On Mon, 02 Feb 2015 13:23:23 +0000, irtcupc wrote:
=20
 my current understanding is that:
 - C: char CompleteInstr[INSTRUCT_LENGTH] is actually a raw chunk - D:
 defining the member as char[INSTRUCT_LENGTH] is an error - the first
 member of a D array is the .length - first char actually stands where
 .length uses to be, which explains the shift.
=20 nope. fixed length arrays doesn't have dedicated `.length` member. try this: =20 align(1) struct _Disasm { align(1): ...
actually, first align is not necessary at all. i.e.: struct _Disasm { align(1): the difference is that `align` before struct tells how structure should=20 be packed (i.e. when you have `_Disasm[2] arr`). and `align` *inside*=20 struct tells compiler how struct *members* should be packed.=
Feb 02 2015
parent reply "irtcupc" <irtcupc nowhere.fi> writes:
On Monday, 2 February 2015 at 13:34:28 UTC, ketmar wrote:
 On Mon, 02 Feb 2015 13:32:57 +0000, ketmar wrote:

 On Mon, 02 Feb 2015 13:23:23 +0000, irtcupc wrote:
 
 my current understanding is that:
 - C: char CompleteInstr[INSTRUCT_LENGTH] is actually a raw 
 chunk - D:
 defining the member as char[INSTRUCT_LENGTH] is an error - 
 the first
 member of a D array is the .length - first char actually 
 stands where
 .length uses to be, which explains the shift.
nope. fixed length arrays doesn't have dedicated `.length` member. try this: align(1) struct _Disasm { align(1): ...
actually, first align is not necessary at all. i.e.: struct _Disasm { align(1): the difference is that `align` before struct tells how structure should be packed (i.e. when you have `_Disasm[2] arr`). and `align` *inside* struct tells compiler how struct *members* should be packed.
Thx, problem fixed, it works now.
Feb 02 2015
next sibling parent FG <home fgda.pl> writes:
On 2015-02-02 at 14:40, irtcupc wrote:
 On Monday, 2 February 2015 at 13:34:28 UTC, ketmar wrote:
   struct _Disasm {
   align(1):

 the difference is that `align` before struct tells how structure should
 be packed (i.e. when you have `_Disasm[2] arr`). and `align` *inside*
 struct tells compiler how struct *members* should be packed.
Thx, problem fixed, it works now.
Yeah, without the align(1) inside the struct, the members of the struct were not crammed, so VirtualAddr started in byte x+8 instead of x+4 (on a 32-bit machine), and that was the source of the extra 4-byte shift you encountered.
Feb 02 2015
prev sibling parent reply "irtcupc " <irtcupc nowhere.fi> writes:
On Monday, 2 February 2015 at 13:40:30 UTC, irtcupc wrote:
 On Monday, 2 February 2015 at 13:34:28 UTC, ketmar wrote:
 On Mon, 02 Feb 2015 13:32:57 +0000, ketmar wrote:

 On Mon, 02 Feb 2015 13:23:23 +0000, irtcupc wrote:
 
 my current understanding is that:
 - C: char CompleteInstr[INSTRUCT_LENGTH] is actually a raw 
 chunk - D:
 defining the member as char[INSTRUCT_LENGTH] is an error - 
 the first
 member of a D array is the .length - first char actually 
 stands where
 .length uses to be, which explains the shift.
nope. fixed length arrays doesn't have dedicated `.length` member. try this: align(1) struct _Disasm { align(1): ...
actually, first align is not necessary at all. i.e.: struct _Disasm { align(1): the difference is that `align` before struct tells how structure should be packed (i.e. when you have `_Disasm[2] arr`). and `align` *inside* struct tells compiler how struct *members* should be packed.
Thx, problem fixed, it works now.
Thx again for your help Ketmar and FG, Thx again for the help in the other Q too (the one about snn imports), I share the binding, it's nothing at all but was a fun to do on a off-day... https://github.com/BBasile/dbeaengine
Feb 04 2015
parent ketmar <ketmar ketmar.no-ip.org> writes:
On Wed, 04 Feb 2015 16:09:24 +0000, irtcupc  wrote:

 Thx again for your help Ketmar and FG, Thx again for the help in the
 other Q too (the one about snn imports), I share the binding,
 it's nothing at all but  was a fun to do on a off-day...
=20
 https://github.com/BBasile/dbeaengine
you may want to add it to dub repo and announce in D.announce. don't=20 think that D.announce is only for big projects, everyone is welcome. ;-)=
Feb 04 2015
prev sibling parent reply Mike Parker <aldacron gmail.com> writes:
On 2/2/2015 9:16 PM, irtcupc wrote:
 The manual section about interfacing from c states that "type[]" is
 inter-compatible from C to D,

 however, I face this strange case:

 - C declaration:
 char identifier[64];

 - D declaration:
 char[64] identifier;

 - the result is only correct if i slice by (- pointer size):
 char[64] fromC(char[64] * thing)
 {
      const offs = size_t.sizeof;
      return thing[-offs.sizeof .. $-offs];
 }

 Is this correct ?
That's looking pretty wonky. You're slicing a pointer to a fixed-size array. Why have you declared the parameter as a pointer? What problem are you trying to solve? It would help a bit to see the declaration of the C function that's giving you the array.
Feb 02 2015
parent "irtcupc" <irtcupc nowhere.fi> writes:
On Monday, 2 February 2015 at 12:57:37 UTC, Mike Parker wrote:
 On 2/2/2015 9:16 PM, irtcupc wrote:
 The manual section about interfacing from c states that 
 "type[]" is
 inter-compatible from C to D,

 however, I face this strange case:

 - C declaration:
 char identifier[64];

 - D declaration:
 char[64] identifier;

 - the result is only correct if i slice by (- pointer size):
 char[64] fromC(char[64] * thing)
 {
     const offs = size_t.sizeof;
     return thing[-offs.sizeof .. $-offs];
 }

 Is this correct ?
That's looking pretty wonky. You're slicing a pointer to a fixed-size array. Why have you declared the parameter as a pointer? What problem are you trying to solve? It would help a bit to see the declaration of the C function that's giving you the array.
It looks like it's here: https://code.google.com/p/beaengine/source/browse/trunk/beaengineSources/Includes/Routines_Disasm.c#763 However i haven't spent the time to dive in there since i'm not a C guy at all.
Feb 02 2015