Re: How to do alias to a C struct member?

2019-04-22 Thread dangbinghoo via Digitalmars-d-learn

On Monday, 22 April 2019 at 15:50:11 UTC, dangbinghoo wrote:

On Monday, 22 April 2019 at 13:10:45 UTC, Adam D. Ruppe wrote:

On Monday, 22 April 2019 at 11:04:49 UTC, dangbinghoo wrote:

alias ifr_ifrn.ifrn_nameifr_name; /* interface name */

So, how to do alias for a C struct member?



D doesn't support this kind of alias. There's two options:



Then you should be able to use it the same way as in C.


OK, I'd prefer with option 2.
thank you in advance!


hi all,

the correct answer is :

---
struct ifreq {
private union ifr_ifrn_ {
byte[IFNAMSIZ] ifrn_name; /* if name, e.g. "en0" */   
}
ifr_ifrn_ ifr_ifrn;

private union ifr_ifru_ {
sockaddr ifru_addr;
sockaddr ifru_dstaddr;
sockaddr ifru_broadaddr;
sockaddr ifru_netmask;
sockaddr ifru_hwaddr;
short   ifru_flags;
int ifru_ivalue;
int ifru_mtu;
ifmap ifru_map;
byte[IFNAMSIZ] ifru_slave;  /* Just fits the size */
byte[IFNAMSIZ] ifru_newname;
byte * ifru_data;
}
ifr_ifru_ ifr_ifru;

	// NOTE: alias will not work : alias ifr_ifrn.ifrn_name	
ifr_name;
	@property ref ifr_name() { return ifr_ifrn.ifrn_name; } /* 
interface name */

---

the `need this` error is telling that `ifr_ifrn` is not an 
instance but a type for my previous code.


so for C struct's union member, we need to first declare a member 
of that union type, and then using property to implement The 
C-Macro.



but here I have a question in further:

 As showing above, ifreq has a member of ``byte[IFNAMSIZ] 
ifrn_name;``, when translating the C style calling code, I need 
to do such a cast for D byte:


  ```
 strcpy(cast(char *)ifr.ifr_name.ptr, 
std.string.toStringz(if_name));

 if (ioctl(s, SIOCGIFHWADDR, ) < 0)
 {
return;
 }
  ```
should I keep the `ifrn_name` to a `char[]` for avoid of doing 
cast D byte to C (char*) ? and I can calling like this:


  ```
struct ifreq {
private union ifr_ifrn_ {
char[IFNAMSIZ] ifrn_name; /* if name, e.g. "en0" */   
}
  ...

 strcpy(ifr.ifr_name.ptr, std.string.toStringz(if_name));
 if (ioctl(s, SIOCGIFHWADDR, ) < 0)
 {
return;
 }

  ```
this looks more clean and like the C style code.


--
Thanks!

Binghoo Dang



Re: How to do alias to a C struct member?

2019-04-22 Thread dangbinghoo via Digitalmars-d-learn
On Monday, 22 April 2019 at 15:45:52 UTC, Arun Chandrasekaran 
wrote:

On Monday, 22 April 2019 at 11:04:49 UTC, dangbinghoo wrote:

hi all,

as now we don't have the net/if.h binding, I need to do struct 
ifreq binding myself, here's my code:


[...]


Looks like we both were working on the same thing, few hours 
apart. 
https://forum.dlang.org/post/nkbnknlgmcwaivppm...@forum.dlang.org


yeah, I was doing that 4 hours ago! ^_^


Re: How to do alias to a C struct member?

2019-04-22 Thread dangbinghoo via Digitalmars-d-learn

On Monday, 22 April 2019 at 13:10:45 UTC, Adam D. Ruppe wrote:

On Monday, 22 April 2019 at 11:04:49 UTC, dangbinghoo wrote:

alias ifr_ifrn.ifrn_nameifr_name; /* interface name */

So, how to do alias for a C struct member?



D doesn't support this kind of alias. There's two options:

1) just write the full name in the code.

ifreq ifr;

ifr.ifr_ifrn.ifrn_name /* instead of ifr.ifrn_name */

or, if you are linking in the D module containing the 
translated headers (if you don't link it in, this will cause 
missing symbol linker errors!)


2) write ref property functions to get to it, using ufcs for 
the middle. So replace that *alias* line with:


@property ref ifr_name(ifreq this_) { return 
this_.ifr_ifrn.ifrn_name; }



Then you should be able to use it the same way as in C.


OK, I'd prefer with option 2.
thank you in advance!


Re: How to do alias to a C struct member?

2019-04-22 Thread Arun Chandrasekaran via Digitalmars-d-learn

On Monday, 22 April 2019 at 11:04:49 UTC, dangbinghoo wrote:

hi all,

as now we don't have the net/if.h binding, I need to do struct 
ifreq binding myself, here's my code:


[...]


Looks like we both were working on the same thing, few hours 
apart. 
https://forum.dlang.org/post/nkbnknlgmcwaivppm...@forum.dlang.org


Re: How to do alias to a C struct member?

2019-04-22 Thread Adam D. Ruppe via Digitalmars-d-learn

On Monday, 22 April 2019 at 11:04:49 UTC, dangbinghoo wrote:

alias ifr_ifrn.ifrn_nameifr_name; /* interface name */

So, how to do alias for a C struct member?



D doesn't support this kind of alias. There's two options:

1) just write the full name in the code.

ifreq ifr;

ifr.ifr_ifrn.ifrn_name /* instead of ifr.ifrn_name */

or, if you are linking in the D module containing the translated 
headers (if you don't link it in, this will cause missing symbol 
linker errors!)


2) write ref property functions to get to it, using ufcs for the 
middle. So replace that *alias* line with:


@property ref ifr_name(ifreq this_) { return 
this_.ifr_ifrn.ifrn_name; }



Then you should be able to use it the same way as in C.


How to do alias to a C struct member?

2019-04-22 Thread dangbinghoo via Digitalmars-d-learn

hi all,

as now we don't have the net/if.h binding, I need to do struct 
ifreq binding myself, here's my code:



struct ifreq {
private union ifr_ifrn {
byte[IFNAMSIZ] ifrn_name; /* if name, e.g. "en0" */   
}

private union ifr_ifru {
sockaddr ifru_addr;
sockaddr ifru_dstaddr;
sockaddr ifru_broadaddr;
sockaddr ifru_netmask;
sockaddr ifru_hwaddr;
short   ifru_flags;
int ifru_ivalue;
int ifru_mtu;
ifmap ifru_map;
byte[IFNAMSIZ] ifru_slave;  /* Just fits the size */
byte[IFNAMSIZ] ifru_newname;
byte * ifru_data;
}

alias ifr_ifrn.ifrn_nameifr_name; /* interface name */
alias ifr_ifru.ifru_hwaddr  ifr_hwaddr;   /* MAC address
*/
alias ifr_ifru.ifru_addrifr_addr; /* address*/
alias ifr_ifru.ifru_dstaddr	ifr_dstaddr;  /* other end of p-p 
lnk	*/
alias ifr_ifru.ifru_broadaddr	ifr_broadaddr;/* broadcast 
address	*/
alias ifr_ifru.ifru_netmask	ifr_netmask;  /* interface net 
mask	*/

alias ifr_ifru.ifru_flags   ifr_flags;/* flags  */
alias ifr_ifru.ifru_ivalue  ifr_metric;   /* metric */
alias ifr_ifru.ifru_mtu ifr_mtu;  /* mtu*/
alias ifr_ifru.ifru_map ifr_map;  /* device map */
alias ifr_ifru.ifru_slave   ifr_slave;/* slave device   
*/
alias ifr_ifru.ifru_data	ifr_data;	  /* for use by 
interface	*/
alias ifr_ifru.ifru_ivalue  ifr_ifindex;  /* interface index  
*/

alias ifr_ifru.ifru_ivalue  ifr_bandwidth;/* link bandwidth */
alias ifr_ifru.ifru_ivalue  ifr_qlen; /* queue length   
*/
alias ifr_ifru.ifru_newname ifr_newname;  /* New name   */
}
---

as show above we need to trun the C code

# define ifr_name   ifr_ifrn.ifrn_name  /* interface name   */

to D's alias, but when done the binding and trying to compiling 
this code:


---
import core.sys.posix.sys.socket;
import core.sys.posix.sys.ioctl;
import core.sys.posix.arpa.inet;

import core.stdc.string;
import core.stdc.stdio;
import core.sys.posix.stdio;
import core.stdc.errno;
import std.string;

..
ifreq ifr;

strcpy(ifr.ifr_name, std.string.toStringz(if_name)); //line 172
if (ioctl(s, SIOCGIFHWADDR, ) < 0)
{
return;
}
---

DMD compiler gives an error :
```
/test.d(172): Error: need this for ifrn_name of type byte[16]
./test.d(172): Error: function core.stdc.string.strcpy(return 
scope char* s1, scope const(char*) s2) is not callable using 
argument types (_error_, immutable(char)*)
./test.d(172):cannot pass argument __error of type 
_error_ to parameter return scope char* s1

```

So, how to do alias for a C struct member?


thanks!

Binghoo Dang