1. What are we trying to achieve (and why)
We're currently trying to communicate with an industrial robot over USB(COM)<->serial(RS232). We would like to control the robot from a C++ application.
2. What setup do we have
We're using Visual Studio C++ 2015 with the built-in C++ compiler. Creating a "Win32 Console Application".
3. What steps have we taken?
We've got the connection working in Processing (Java) using Serial but we would like to implement it in C++.
3.1 Boost ASIO
We're using Boost ASIO (installed with NuGet package manager).
At this point we get 2 compile errors indicating the same problem:
Error C2694 'const char *asio::detail::system_category::name(void) const': overriding virtual function has less restrictive exception specification than base class virtual member function 'const char *std::error_category::name(void) noexcept const'
I figured that this error is most likely not caused by my code (I haven't changed the library). So I believe the VS21015 C++ compiler is not fully compatible with boost::asio?
I've found two other links/posts with somewhat the same error:
https://github.com/chriskohlhoff/asio/issues/35
And I tried the following define:
#ifndef ASIO_ERROR_CATEGORY_NOEXCEPT
#define ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true)
#endif // !defined(ASIO_ERROR_CATEGORY_NOEXCEPT)
Error in websocketpp library and boost in windows Visual Studio 2015
With the following define:
#define ASIO_ERROR_CATEGORY_NOEXCEPT noexcept(true)
//or
#define ASIO_ERROR_CATEGORY_NOEXCEPT 1
But it did not resolve the errors. The even caused a lot of random syntax errors and undeclared identifiers (which would indicate missing the include of iterator.
3.2 Windows(base) and C
We've used some C code (and added in a little C++ Debugging) to detect COM ports. But it simply doesn't show them (however it does in device explorer). We even had to convert a LPCWSTR to char array (wtf?).
#include <stdio.h>
#include <cstdio>
#include <iostream>
#include <windows.h>
#include <winbase.h>
wchar_t *convertCharArrayToLPCWSTR(const char* charArray)
{
wchar_t* wString = new wchar_t[4096];
MultiByteToWideChar(CP_ACP, 0, charArray, -1, wString, 4096);
return wString;
}
BOOL COM_exists(int port)
{
char buffer[7];
COMMCONFIG CommConfig;
DWORD size;
if (!(1 <= port && port <= 255))
{
return FALSE;
}
snprintf(buffer, sizeof buffer, "COM%d", port);
size = sizeof CommConfig;
// COM port exists if GetDefaultCommConfig returns TRUE
// or changes <size> to indicate COMMCONFIG buffer too small.
std::cout << "COM" << port << " | " << (GetDefaultCommConfig(convertCharArrayToLPCWSTR(buffer), &CommConfig, &size)
|| size > sizeof CommConfig) << std::endl;
return (GetDefaultCommConfig(convertCharArrayToLPCWSTR(buffer), &CommConfig, &size)
|| size > sizeof CommConfig);
}
int main()
{
int i;
for (i = 1; i < 256; ++i)
{
if (COM_exists(i))
{
printf("COM%d exists\n", i);
}
}
std::cin.get();
return 0;
}
3.3 Another Serial.h from the internet
I believe it was from: http://www.codeguru.com/cpp/i-n/network/serialcommunications/article.php/c2503/CSerial--A-C-Class-for-Serial-Communications.htm
Same rules, I include the library, everything compiles fine. (Test written below)
#include <iostream>
#include <string>
#include "Serial.h"
int main(void)
{
CSerial serial;
if (serial.Open(8, 9600))
std::cout << "Port opened successfully" << std::endl;
else
std::cout << "Failed to open port!" << std::endl;
std::cin.get();
return 0;
}
But it still doesn't show my COM ports... (They do show up in device explorer though.)
4 So what is actually working?
This particular piece of code WILL display the right COM port...
TCHAR lpTargetPath[5000]; // buffer to store the path of the COMPORTS
DWORD test;
for (int i = 0; i<255; i++) // checking ports from COM0 to COM255
{
CString str;
str.Format(_T("%d"), i);
CString ComName = CString("COM") + CString(str); // converting to COM0, COM1, COM2
test = QueryDosDevice(ComName, lpTargetPath, 5000);
// Test the return value and error if any
if (test != 0) //QueryDosDevice returns zero if it didn't find an object
{
std::cout << "COM" << i << std::endl; // add to the ComboBox
}
}