Reputation: 115
I am writing a vc++ CLR form project which will control my robot via the serial port. The robot expects an ASCII command as follows: First byte is a character between A and Z which determines the command to execute, the second character is a + or - sign, then there are exactly 5 numbers. If the number to send is less than 5 digits then it is padded with zeros at the start.
I am using System::IO::Ports::SerialPort to communicate with the COM port which has the following prototype:
public:
void Write(
array<wchar_t>^ buffer,
int offset,
int count
)
Since I need to pad the number so it is exactly 5 digits, I am using sprintf. (I am still learning c++ and have not had much experience with String::Format yet, but I assume I can do the same thing there just as easily - but for now I want to do it using these arrays, for the sake of learning).
sprintf returns the string of wchar_t, I now need to add these wchar_t to an < array > to pass to the function however I am having trouble find an elegant solution to this. The solution I have works, however the for loops feel really hacky to me:
int DeltaForm::setThetas(int th1, int th2, int th3)
{
// Cannot write more than 5 digits
if (th1 < 1000 && th2 < 1000 && th3 < 1000)
{
wchar_t commandBuffer[8];
array<wchar_t>^ buffer = gcnew array<wchar_t>(8);
_snwprintf_s(commandBuffer, 8, 7, L"B+%05d", th2*100);
for (int i = 0; i < 8; i++)
{
buffer->SetValue(commandBuffer[i], i);
}
this->serialComms->Write(buffer, 0, 7);
_snwprintf_s(commandBuffer, 8, 7, L"A+%05d", th1*100);
for (int i = 0; i < 8; i++)
{
buffer->SetValue(commandBuffer[i], i);
}
this->serialComms->Write(buffer, 0, 7);
_snwprintf_s(commandBuffer, 8, 7, L"C+%05d", th3*100);
for (int i = 0; i < 8; i++)
{
buffer->SetValue(commandBuffer[i], i);
}
this->serialComms->Write(buffer, 0, 7);
}
else
{
return 0;
}
}
I have had a look through the array class but could not find any methods which would help me. Is there a simpler, more elegant way to populate an array?
Thanks
Upvotes: 2
Views: 1791
Reputation: 14880
If you pin a pointer to the array you can treat it natively, for example:
array<wchar_t>^ buffer = gcnew array<wchar_t>(8);
pin_ptr<wchar_t> p = &buffer[0];
_snwprintf_s(p, 8, 7, L"B+%05d", th2*100);
this->serialComms->Write(buffer, 0, 7);
I'd also like to elaborate on the point @Adriano made. It seems that you are using Managed C++ throughout your code, and while it was specifically designed to mix C++ with the CLR,it is better to stick to one methodology.
System::String^ command = String::Format("B+{0:00000}", th2*100);
array<Byte>^ command_buffer = System::Text::Encoding::Unicode->GetBytes(command);
The example uses Unicode because UTF-16 is used by the Windows operating system to represent wchar values, but you should switch that to ASCII if that's what expected on the wire.
Upvotes: 2