UDP sockets in D Programming Language

d, python, sockets, udp

Solution

For starters, you'll want `ArtNetDMX` to be a `struct`, not a `class` - since classes in D are reference types and there are no guarantees about class field layout; and since you're sending it over the wire, specify the appropriate alignment (usually 1 if every field is to be packed together):

struct ArtNetDMX {
    align(1):
    ....
}

In your `main`, you can now allocate an instance of it on the stack:

ArtNetDMX packet;        // no `new` required

packet.id = "ART-NET0";  // initialize fields
packet.opCode = 0x5000;
packet.ver = 14;
packet.universe = 0;
packet.lengthHi = 2;

Or if you perform the same initialization a lot, move it into a function:

ArtNetDMX createArtNetDMX()
{
    ArtNetDMX packet;

    packet.id = "ART-NET0";
    packet.opCode = 0x5000;
    packet.ver = 14;
    packet.universe = 0;
    packet.lengthHi = 2;

    return packet;
}

Finally, `Socket.send` requires its parameter to be a slice (an array or part of). If you end up sending multiple packets at a time, you'd put your packets into an array, then just send the array.

Since you're only sending one packet, you can replace

s.send(packet);

with

s.send((&packet)[0..1]);

which is just a safe way to convert an object to a 1-element slice.

Problem

I'm attempting to convert a python program to D; the program is for sending Art-Net DMX packets. Python: ``` import sys, socket, math, time from ctypes import * class ArtNetDMXOut(LittleEndianStructure): PORT = 0x1936 _fields_ = [("id", c_char * 8), ("opcode", c_ushort), ("protverh", c_ubyte), ("protver", c_ubyte), ("sequence", c_ubyte), ("physical", c_ubyte), ("universe", c_ushort), ("lengthhi", c_ubyte), ("length", c_ubyte), ("payload", c_ubyte * 512)] def __init__(self): self.id = b"Art-Net" self.opcode = 0x5000 self.protver = 14 self.universe = 0 self.lengthhi = 2 def main(): hostIP = "localhost" S = socket.socket(socket.AF_INET,socket.SOCK_DGRAM) packet = ArtNetDMXOut() packet.payload[0] = 255 S.sendto(packet, (hostIP, ArtNetDMXOut.PORT)) if __name__ == "__main__": main() ``` D: ``` import std.stdio; import std.socket; class ArtNetDMX{ char id[8]; ushort opCode; ubyte verH; ubyte ver; ubyte sequence; ubyte physical; ushort universe; ubyte lengthHi; ubyte length; ubyte data[511]; this(){ this.id = "ART-NET0"; this.opCode = 0x5000; this.ver = 14; this.universe = 0; this.lengthHi = 2; } } void main() { auto s = new UdpSocket(); auto addr = new InternetAddress("localhost", 6454); s.bind(addr); ArtNetDMX packet = new ArtNetDMX(); packet.data[0] = 255; s.send(packet); }; ``` My Python code works exactly as intended, but in D I get the error `function std.socket.Socket.send (const(void)[] buf, SocketFlags flags) is not callable using argument types (ArtNetDMX)` at the `s.send(packet);` line. Am I approaching this correctly? What am I doing wrong?

Original source