Wednesday, August 01, 2012

Pitfalls of C++/CLI

I'm a C/C++ guy. I've written a lot of software for Windows using VC++ - from VC++ 6 to VC++ 2010 - but always used native code - e.g. no .NET stuff.

I recently inherited a project at work that had a mix of C# and C++/CLI. The C# stuff is actually pretty minimal - just enough to manage a Windows Service. The C++/CLI makes up the majority of the program, and is also tied with some Native C++ to interface to a driver DLL for some special hardware.

Long story short, I'm trying to determine the cause of some buffering issues between this Windows application and a Linux-based application. The Linux-based application works with other software that does the same thing just fine; but there's a bug somewhere I'm trying to track down. In the midst of analyzing the Windows application I find some code that essentially does the following:

struct myCppStructure
    unsigned int field1;
    unsigned int field2;
    unsigned int dataArray[512];
struct myCppStructure* data;
IntPtr dataPtr(data);
// myNetworkSocket is a NetworkStream cast as a System::IO::Stream^ System::IO::BinaryWriter^

myBinWriter = gcnew BinaryWriter(myNetworkSocket);
__int64 length = sizeof(struct myCppStructure) / sizeof(__int64);
unsigned __int64* ptr = static_cast<unsigned __int64>(dataPtr.toPointer());

for (unsigned int i = 0; i < (length / sizeof(unsigned __int64)); i++)
// then calculate the remainder of the structure size and send that

What bothers me is that in nearly all other toolkits you don't need the FOR loop to write the data. You could do something like:

myBinWriter->Write(data, sizeof(struct myCppStructure));

I've been trying to find an equivalent in C++/CLI, but it seems everything has to go through some other object do it - usually resulting a copy of some sort, which is not permissible where this code is working.

So it seems that something that is extremely basic is just completely utterly lacking in C++/CLI. Simple things like this make it an useless language.

If anyone knows the solution, then please link it in the comments.