1.我们想要实现什么(以及为什么)
我们目前正试图与一个人沟通 产业 </跨度> 机器人通过USB(COM)&lt; - &gt;串行(RS232)。我们想从C ++应用程序控制机器人。
2 )) { printf(“COM%d存在\ n”,i); } } 的std :: cin.get(); 返回0;}
3.3另一个Serial.h来自 互联网 </跨度>
我相信它来自:http://www.codeguru.com/cpp/i-n/network
如果你还没有,可能需要更新到更新版本的boost。
第二部分的问题是您命名COM端口。只有COM1到4可以是'秃头'名称。您需要将其格式化为:
\\.\COM9
在这里清楚地处理转义序列:
snprintf(buffer, sizeof(buffer), "\\\\.\\COM%d", port);
编辑:实际上你不需要使用GetCommConfig,只需使用CreateFile打开端口。它应该工作。我怀疑你转换成宽字符串。
您可能还会发现首先加载cfgmgr32.dll库的性能增强。
使用CreateFile进行COM端口检测可能会导致某些Windows系统上出现BSOD。特定的罪魁祸首是一些软件调制解调器和一些显示COM端口的蓝牙设备。所以使用GetDefaultCommConfig是一种普遍的方式,虽然它可能不适用于所有端口。
那你还能做什么呢?使用setupapi.dll。可悲的是,这并非完全无足轻重......
namespace { typedef HKEY (__stdcall *OpenDevRegKey)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, DWORD, DWORD, REGSAM); typedef BOOL (__stdcall *ClassGuidsFromName)(LPCTSTR, LPGUID, DWORD, PDWORD); typedef BOOL (__stdcall *DestroyDeviceInfoList)(HDEVINFO); typedef BOOL (__stdcall *EnumDeviceInfo)(HDEVINFO, DWORD, PSP_DEVINFO_DATA); typedef HDEVINFO (__stdcall *GetClassDevs)(LPGUID, LPCTSTR, HWND, DWORD); typedef BOOL (__stdcall *GetDeviceRegistryProperty)(HDEVINFO, PSP_DEVINFO_DATA, DWORD, PDWORD, PBYTE, DWORD, PDWORD); } // namespace typedef std::basic_string<TCHAR> tstring; struct PortEntry { tstring dev; tstring name; bool operator== (tstring const& device) const { return dev == device; // TODO maybe use case-insentitive compare. } bool operator!= (tstring const& device) const { return !(*this == device); } }; typedef std::vector<PortEntry> PortList; // ... DllHandler setupapi; // RAII class for LoadLibrary / FreeLibrary if (!setupapi.load(_T("SETUPAPI.DLL"))) { throw std::runtime_error("Can\'t open setupapi.dll"); } OpenDevRegKey fnOpenDevRegKey = setupapi.GetProc("SetupDiOpenDevRegKey"); ClassGuidsFromName fnClassGuidsFromName = #ifdef UNICODE setupapi.GetProc("SetupDiClassGuidsFromNameW"); #else setupapi.GetProc("SetupDiClassGuidsFromNameA"); #endif DestroyDeviceInfoList fnDestroyDeviceInfoList = setupapi.GetProc("SetupDiDestroyDeviceInfoList"); EnumDeviceInfo fnEnumDeviceInfo = setupapi.GetProc("SetupDiEnumDeviceInfo"); GetClassDevs fnGetClassDevs = #ifdef UNICODE setupapi.GetProc("SetupDiGetClassDevsW"); #else setupapi.GetProc("SetupDiGetClassDevsA"); #endif GetDeviceRegistryProperty fnGetDeviceRegistryProperty = #ifdef UNICODE setupapi.GetProc("SetupDiGetDeviceRegistryPropertyW"); #else setupapi.GetProc("SetupDiGetDeviceRegistryPropertyA"); #endif if ((fnOpenDevRegKey == 0) || (fnClassGuidsFromName == 0) || (fnDestroyDeviceInfoList == 0) || (fnEnumDeviceInfo == 0) || (fnGetClassDevs == 0) || (fnGetDeviceRegistryProperty == 0) ) { throw std:runtime_error( "Could not locate required functions in setupapi.dll" ); } // First need to get the GUID from the name "Ports" // DWORD dwGuids = 0; (*fnClassGuidsFromName)(_T("Ports"), NULL, 0, &dwGuids); if (dwGuids == 0) { throw std::runtime_error("Can\'t get GUIDs from \'Ports\' key in the registry"); } // Allocate the needed memory std::vector<GUID> guids(dwGuids); // Get the GUIDs if (!(*fnClassGuidsFromName)(_T("Ports"), &guids[0], dwGuids, &dwGuids)) { throw std::runtime_error("Can\'t get GUIDs from \'Ports\' key in the registry"); } // Now create a "device information set" which is required to enumerate all the ports HDEVINFO hdevinfoset = (*fnGetClassDevs)(&guids[0], NULL, NULL, DIGCF_PRESENT); if (hdevinfoset == INVALID_HANDLE_VALUE) { throw std::runtime_error("Can\'t get create device information set."); } // Finished with the guids. guids.clear(); // Finally do the enumeration bool more = true; int index = 0; SP_DEVINFO_DATA devinfo; while (more) { //Enumerate the current device devinfo.cbSize = sizeof(SP_DEVINFO_DATA); more = (0 != (*fnEnumDeviceInfo)(hdevinfoset, index, &devinfo)); if (more) { PortEntry entry; //Did we find a serial port for this device bool added = false; //Get the registry key which stores the ports settings HKEY hdevkey = (*fnOpenDevRegKey)( hdevinfoset, &devinfo, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_QUERY_VALUE ); if (hdevkey) { //Read in the name of the port TCHAR port_name[256]; DWORD size = sizeof(port_name); DWORD type = 0; if ((::RegQueryValueEx( hdevkey, _T("PortName"), NULL, &type, (LPBYTE) port_name, &size ) == ERROR_SUCCESS) && (type == REG_SZ) ) { // If it looks like "COMX" then // add it to the array which will be returned tstring s = port_name; size_t len = s.length(); String const cmp(s, 0, 3); if (CaseInsensitiveCompareEqual(String("COM"), cmp)) { entry.name = s; entry.dev = "\\\\.\\" + s; added = true; } } // Close the key now that we are finished with it ::RegCloseKey(hdevkey); } // If the port was a serial port, then also try to get its friendly name if (added) { TCHAR friendly_name[256]; DWORD size = sizeof(friendly_name); DWORD type = 0; if ((fnGetDeviceRegistryProperty)( hdevinfoset, &devinfo, SPDRP_DEVICEDESC, &type, (PBYTE)friendly_name, size, &size ) && (type == REG_SZ) ) { entry.name += _T(" ("); entry.name += friendly_name; entry.name += _T(")"); } // // Add the port to our vector. // // If we already have an entry for the given device, then // overwrite it (this will add the friendly name). // PortList::iterator i = std::find( ports.begin(), ports.end(), entry.dev ); if (i == ports.end()) { ports.push_back(entry); } else { (*i) = entry; } } } ++index; } // Free up the "device information set" now that we are finished with it (*fnDestroyDeviceInfoList)(hdevinfoset);
你需要做一些工作才能使这个可编辑,但它应该工作。 看到 https://support.microsoft.com/en-us/kb/259695