4

I am writing a program to interact with the management interface for a piece of equipment over TCP. The problem is, the documentation for the equipment is written in C, while the program I am writing is in C#. My problem is, the documentation specifies

The communication is based upon the C structure-based API buffer

No amount of Googling can seem to point me to this API or how I send a raw structure across TCP. The documentation seems to imply that I should use memcpy to copy the struct to the TCP buffer, but C# doesn't directly support memcpy. Is there an equivelant method in C# or a different way to accomplish this

DaveB
  • 2,199
  • 2
  • 14
  • 11
  • You are about to meet up with the ugliness of streams. There are some tips [here](http://stackoverflow.com/questions/11804131/asynchronous-tcp-socket-bytes-merging). – HABO Aug 14 '12 at 14:37
  • This question is a perfect illustration of why the network protocol should never have been based on C structs in the first place. Protocol designers please take note. – user207421 Aug 14 '12 at 23:23

2 Answers2

5

You could build a .Net version of your C struct, then use marshalling to send a byte array through the network. Here's an example with the MLocation C struct.

[StructLayout(LayoutKind.Sequential, Pack = 8)]
public struct MLocation
{
    public int x;
    public int y;
};

public static void Main()
{
    MLocation test = new MLocation();

    // Gets size of struct in bytes
    int structureSize = Marshal.SizeOf(test);

    // Builds byte array
    byte[] byteArray = new byte[structureSize];

    IntPtr memPtr = IntPtr.Zero;

    try
    {
        // Allocate some unmanaged memory
        memPtr = Marshal.AllocHGlobal(structureSize);

        // Copy struct to unmanaged memory
        Marshal.StructureToPtr(test, memPtr, true);

        // Copies to byte array
        Marshal.Copy(memPtr, byteArray, 0, structureSize);
    }
    finally
    {
        if (memPtr != IntPtr.Zero)
        {
            Marshal.FreeHGlobal(memPtr);
        }
    }

    // Now you can send your byte array through TCP
    using (TcpClient client = new TcpClient("host", 8080))
    {
        using (NetworkStream stream = client.GetStream())
        {
            stream.Write(byteArray, 0, byteArray.Length);
        }
    }

    Console.ReadLine();
}
ken2k
  • 48,145
  • 10
  • 116
  • 176
  • Why do you have to use the unmanaged memory in order to copy to the bytearray? Isn't possible copy to the bytearray directly? I guess is something with how C# works but explanation will be good.. – Ron Mar 07 '19 at 09:20
0

You will use either unsafe structs,the BitConverter or write a managed C++ wrapper to fill the API buffer.
Essentially you are doing P/Invoke with calling a socket instead of calling a function.

weismat
  • 7,195
  • 3
  • 43
  • 58