Linker Error

Please support our C++ advertiser: Intel Parallel Studio Home
Thread Solved

Join Date: Feb 2007
Posts: 5
Reputation: Caped Sam is an unknown quantity at this point 
Solved Threads: 0
Caped Sam Caped Sam is offline Offline
Newbie Poster

Linker Error

 
0
  #1
Feb 2nd, 2007
Hi, I'm very new to C++ and I am getting the following error when I try to compile:

[Linker error] undefined reference to `CSerial::CSerial()'
[Linker error] undefined reference to `CSerial::Open(char const*, unsigned long, unsigned long, bool)'
[Linker error] undefined reference to `CSerial::~CSerial()'
.
.
.
etc.

This is the code that I am trying to compile:
  1.  
  2. #define STRICT
  3. #include <tchar.h>
  4. #include <windows.h>
  5. #include "Serial.h"
  6.  
  7.  
  8. int ShowError (LONG lError, LPCTSTR lptszMessage)
  9. {
  10. // Generate a message text
  11. TCHAR tszMessage[256];
  12. wsprintf(tszMessage,_T("%s\n(error code %d)"), lptszMessage, lError);
  13.  
  14. // Display message-box and return with an error-code
  15. ::MessageBox(0,tszMessage,_T("Hello world"), MB_ICONSTOP|MB_OK);
  16. return 1;
  17. }
  18.  
  19. int WINAPI _tWinMain (HINSTANCE /*hInst*/, HINSTANCE /*hInstPrev*/, LPTSTR /*lptszCmdLine*/, int /*nCmdShow*/)
  20. {
  21. CSerial serial;
  22. LONG lLastError = ERROR_SUCCESS;
  23.  
  24. // Attempt to open the serial port (COM1)
  25. lLastError = serial.Open(_T("COM1"),0,0,false);
  26. if (lLastError != ERROR_SUCCESS)
  27. return ::ShowError(serial.GetLastError(), _T("Unable to open COM-port"));
  28.  
  29. // Setup the serial port (9600,N81) using hardware handshaking
  30. lLastError = serial.Setup(CSerial::EBaud9600,CSerial::EData8,CSerial::EParNone,CSerial::EStop1);
  31. if (lLastError != ERROR_SUCCESS)
  32. return ::ShowError(serial.GetLastError(), _T("Unable to set COM-port setting"));
  33.  
  34. // Setup handshaking
  35. lLastError = serial.SetupHandshaking(CSerial::EHandshakeHardware);
  36. if (lLastError != ERROR_SUCCESS)
  37. return ::ShowError(serial.GetLastError(), _T("Unable to set COM-port handshaking"));
  38.  
  39. // The serial port is now ready and we can send/receive data. If
  40. // the following call blocks, then the other side doesn't support
  41. // hardware handshaking.
  42. lLastError = serial.Write("Hello world\n");
  43. if (lLastError != ERROR_SUCCESS)
  44. return ::ShowError(serial.GetLastError(), _T("Unable to send data"));
  45.  
  46. // Close the port again
  47. serial.Close();
  48. return 0;
  49. }
The 'Serial.h' header file can be downloaded (along with the code) here:

http://www.codeproject.com/system/Se...erial_demo.zip
or
http://www.codeproject.com/system/serial.asp

I am using DevC++

Basically I am trying to write a program to control an external power supply using a serial port. I can tell the power supply what to do using hyperterminal, so I know the connection is working. I'm just inexperienced in doing the serial communications port stuff with C++ so I'm trying to learn through this guy's demo project.

Any help with this Linker Error or this application would be amazing!

-Sam Cape
Last edited by Caped Sam; Feb 2nd, 2007 at 12:56 pm. Reason: typo
Reply With Quote Quick reply to this message  
Join Date: Jun 2006
Posts: 7,618
Reputation: ~s.o.s~ has much to be proud of ~s.o.s~ has much to be proud of ~s.o.s~ has much to be proud of ~s.o.s~ has much to be proud of ~s.o.s~ has much to be proud of ~s.o.s~ has much to be proud of ~s.o.s~ has much to be proud of ~s.o.s~ has much to be proud of ~s.o.s~ has much to be proud of 
Solved Threads: 467
Super Moderator
Featured Poster
~s.o.s~'s Avatar
~s.o.s~ ~s.o.s~ is offline Offline
Failure as a human

Re: Linker Error

 
0
  #2
Feb 2nd, 2007
Linker errors are usually generated when the linker can't find the function definations i.e. the body of the mentioned functions.

You need to place the "Serial.h" and "Serial.cpp" file in the same directory as that of the main or driver file and make sure the above mentioned functions are defined in the "Serial.cpp" file.
I don't accept change; I don't deserve to live.
Reply With Quote Quick reply to this message  
Join Date: Feb 2007
Posts: 5
Reputation: Caped Sam is an unknown quantity at this point 
Solved Threads: 0
Caped Sam Caped Sam is offline Offline
Newbie Poster

Re: Linker Error

 
0
  #3
Feb 2nd, 2007
Originally Posted by ~s.o.s~ View Post
Linker errors are usually generated when the linker can't find the function definations i.e. the body of the mentioned functions.

You need to place the "Serial.h" and "Serial.cpp" file in the same directory as that of the main or driver file and make sure the above mentioned functions are defined in the "Serial.cpp" file.
I tried what you asked and got the same error. I placed my 'hello world' file in the same directory that contains the "Serial.h" file and the "Serial.cpp" file. I also made sure that the list of directories in my compiler's include path contained the directory where all 3 of these files live.

For reference, here is the code for each of the files:

  1. // Serial.cpp - Implementation of the CSerial class
  2. //
  3. // Copyright (C) 1999-2003 Ramon de Klein (Ramon.de.Klein@ict.nl)
  4. //
  5. // This library is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU Lesser General Public
  7. // License as published by the Free Software Foundation; either
  8. // version 2.1 of the License, or (at your option) any later version.
  9. //
  10. // This library is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. // Lesser General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU Lesser General Public
  16. // License along with this library; if not, write to the Free Software
  17. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18.  
  19.  
  20. //////////////////////////////////////////////////////////////////////
  21. // Include the standard header files
  22.  
  23. #define STRICT
  24. #include <crtdbg.h>
  25. #include <tchar.h>
  26. #include <windows.h>
  27.  
  28.  
  29. //////////////////////////////////////////////////////////////////////
  30. // Include module headerfile
  31.  
  32. #include "Serial.h"
  33.  
  34.  
  35. //////////////////////////////////////////////////////////////////////
  36. // Disable warning C4127: conditional expression is constant, which
  37. // is generated when using the _RPTF and _ASSERTE macros.
  38.  
  39. #pragma warning(disable: 4127)
  40.  
  41.  
  42. //////////////////////////////////////////////////////////////////////
  43. // Enable debug memory manager
  44.  
  45. #ifdef _DEBUG
  46.  
  47. #ifdef THIS_FILE
  48. #undef THIS_FILE
  49. #endif
  50.  
  51. static const char THIS_FILE[] = __FILE__;
  52. #define new DEBUG_NEW
  53.  
  54. #endif
  55.  
  56.  
  57. //////////////////////////////////////////////////////////////////////
  58. // Helper methods
  59.  
  60. inline void CSerial::CheckRequirements (LPOVERLAPPED lpOverlapped, DWORD dwTimeout) const
  61. {
  62. #ifdef SERIAL_NO_OVERLAPPED
  63.  
  64. // Check if an overlapped structure has been specified
  65. if (lpOverlapped || (dwTimeout != INFINITE))
  66. {
  67. // Quit application
  68. ::MessageBox(0,_T("Overlapped I/O and time-outs are not supported, when overlapped I/O is disabled."),_T("Serial library"), MB_ICONERROR | MB_TASKMODAL);
  69. ::DebugBreak();
  70. ::ExitProcess(0xFFFFFFF);
  71. }
  72.  
  73. #endif
  74.  
  75. #ifdef SERIAL_NO_CANCELIO
  76.  
  77. // Check if 0 or INFINITE time-out has been specified, because
  78. // the communication I/O cannot be cancelled.
  79. if ((dwTimeout != 0) && (dwTimeout != INFINITE))
  80. {
  81. // Quit application
  82. ::MessageBox(0,_T("Timeouts are not supported, when SERIAL_NO_CANCELIO is defined"),_T("Serial library"), MB_ICONERROR | MB_TASKMODAL);
  83. ::DebugBreak();
  84. ::ExitProcess(0xFFFFFFF);
  85. }
  86.  
  87. #endif // SERIAL_NO_CANCELIO
  88.  
  89. // Avoid warnings
  90. (void) dwTimeout;
  91. (void) lpOverlapped;
  92. }
  93.  
  94. inline BOOL CSerial::CancelCommIo (void)
  95. {
  96. #ifdef SERIAL_NO_CANCELIO
  97. // CancelIo shouldn't have been called at this point
  98. ::DebugBreak();
  99. return FALSE;
  100. #else
  101.  
  102. // Cancel the I/O request
  103. return ::CancelIo(m_hFile);
  104.  
  105. #endif // SERIAL_NO_CANCELIO
  106. }
  107.  
  108.  
  109. //////////////////////////////////////////////////////////////////////
  110. // Code
  111.  
  112. CSerial::CSerial ()
  113. : m_lLastError(ERROR_SUCCESS)
  114. , m_hFile(0)
  115. , m_eEvent(EEventNone)
  116. , m_dwEventMask(0)
  117. #ifndef SERIAL_NO_OVERLAPPED
  118. , m_hevtOverlapped(0)
  119. #endif
  120. {
  121. }
  122.  
  123. CSerial::~CSerial ()
  124. {
  125. // If the device is already closed,
  126. // then we don't need to do anything.
  127. if (m_hFile)
  128. {
  129. // Display a warning
  130. _RPTF0(_CRT_WARN,"CSerial::~CSerial - Serial port not closed\n");
  131.  
  132. // Close implicitly
  133. Close();
  134. }
  135. }
  136.  
  137. CSerial::EPort CSerial::CheckPort (LPCTSTR lpszDevice)
  138. {
  139. // Try to open the device
  140. HANDLE hFile = ::CreateFile(lpszDevice,
  141. GENERIC_READ|GENERIC_WRITE,
  142. 0,
  143. 0,
  144. OPEN_EXISTING,
  145. 0,
  146. 0);
  147.  
  148. // Check if we could open the device
  149. if (hFile == INVALID_HANDLE_VALUE)
  150. {
  151. // Display error
  152. switch (::GetLastError())
  153. {
  154. case ERROR_FILE_NOT_FOUND:
  155. // The specified COM-port does not exist
  156. return EPortNotAvailable;
  157.  
  158. case ERROR_ACCESS_DENIED:
  159. // The specified COM-port is in use
  160. return EPortInUse;
  161.  
  162. default:
  163. // Something else is wrong
  164. return EPortUnknownError;
  165. }
  166. }
  167.  
  168. // Close handle
  169. ::CloseHandle(hFile);
  170.  
  171. // Port is available
  172. return EPortAvailable;
  173. }
  174.  
  175. LONG CSerial::Open (LPCTSTR lpszDevice, DWORD dwInQueue, DWORD dwOutQueue, bool fOverlapped)
  176. {
  177. // Reset error state
  178. m_lLastError = ERROR_SUCCESS;
  179.  
  180. // Check if the port isn't already opened
  181. if (m_hFile)
  182. {
  183. m_lLastError = ERROR_ALREADY_INITIALIZED;
  184. _RPTF0(_CRT_WARN,"CSerial::Open - Port already opened\n");
  185. return m_lLastError;
  186. }
  187.  
  188. // Open the device
  189. m_hFile = ::CreateFile(lpszDevice,
  190. GENERIC_READ|GENERIC_WRITE,
  191. 0,
  192. 0,
  193. OPEN_EXISTING,
  194. fOverlapped?FILE_FLAG_OVERLAPPED:0,
  195. 0);
  196. if (m_hFile == INVALID_HANDLE_VALUE)
  197. {
  198. // Reset file handle
  199. m_hFile = 0;
  200.  
  201. // Display error
  202. m_lLastError = ::GetLastError();
  203. _RPTF0(_CRT_WARN, "CSerial::Open - Unable to open port\n");
  204. return m_lLastError;
  205. }
  206.  
  207. #ifndef SERIAL_NO_OVERLAPPED
  208. // We cannot have an event handle yet
  209. _ASSERTE(m_hevtOverlapped == 0);
  210.  
  211. // Create the event handle for internal overlapped operations (manual reset)
  212. if (fOverlapped)
  213. {
  214. m_hevtOverlapped = ::CreateEvent(0,true,false,0);
  215. if (m_hevtOverlapped == 0)
  216. {
  217. // Obtain the error information
  218. m_lLastError = ::GetLastError();
  219. _RPTF0(_CRT_WARN,"CSerial::Open - Unable to create event\n");
  220.  
  221. // Close the port
  222. ::CloseHandle(m_hFile);
  223. m_hFile = 0;
  224.  
  225. // Return the error
  226. return m_lLastError;
  227. }
  228. }
  229. #else
  230.  
  231. // Overlapped flag shouldn't be specified
  232. _ASSERTE(!fOverlapped);
  233.  
  234. #endif
  235.  
  236. // Setup the COM-port
  237. if (dwInQueue || dwOutQueue)
  238. {
  239. // Make sure the queue-sizes are reasonable sized. Win9X systems crash
  240. // if the input queue-size is zero. Both queues need to be at least
  241. // 16 bytes large.
  242. _ASSERTE(dwInQueue >= 16);
  243. _ASSERTE(dwOutQueue >= 16);
  244.  
  245. if (!::SetupComm(m_hFile,dwInQueue,dwOutQueue))
  246. {
  247. // Display a warning
  248. long lLastError = ::GetLastError();
  249. _RPTF0(_CRT_WARN,"CSerial::Open - Unable to setup the COM-port\n");
  250.  
  251. // Close the port
  252. Close();
  253.  
  254. // Save last error from SetupComm
  255. m_lLastError = lLastError;
  256. return m_lLastError;
  257. }
  258. }
  259.  
  260. // Setup the default communication mask
  261. SetMask();
  262.  
  263. // Non-blocking reads is default
  264. SetupReadTimeouts(EReadTimeoutNonblocking);
  265.  
  266. // Setup the device for default settings
  267. COMMCONFIG commConfig = {0};
  268. DWORD dwSize = sizeof(commConfig);
  269. commConfig.dwSize = dwSize;
  270. if (::GetDefaultCommConfig(lpszDevice,&commConfig,&dwSize))
  271. {
  272. // Set the default communication configuration
  273. if (!::SetCommConfig(m_hFile,&commConfig,dwSize))
  274. {
  275. // Display a warning
  276. _RPTF0(_CRT_WARN,"CSerial::Open - Unable to set default communication configuration.\n");
  277. }
  278. }
  279. else
  280. {
  281. // Display a warning
  282. _RPTF0(_CRT_WARN,"CSerial::Open - Unable to obtain default communication configuration.\n");
  283. }
  284.  
  285. // Return successful
  286. return m_lLastError;
  287. }
  288.  
  289. LONG CSerial::Close (void)
  290. {
  291. // Reset error state
  292. m_lLastError = ERROR_SUCCESS;
  293.  
  294. // If the device is already closed,
  295. // then we don't need to do anything.
  296. if (m_hFile == 0)
  297. {
  298. // Display a warning
  299. _RPTF0(_CRT_WARN,"CSerial::Close - Method called when device is not open\n");
  300. return m_lLastError;
  301. }
  302.  
  303. #ifndef SERIAL_NO_OVERLAPPED
  304. // Free event handle
  305. if (m_hevtOverlapped)
  306. {
  307. ::CloseHandle(m_hevtOverlapped);
  308. m_hevtOverlapped = 0;
  309. }
  310. #endif
  311.  
  312. // Close COM port
  313. ::CloseHandle(m_hFile);
  314. m_hFile = 0;
  315.  
  316. // Return successful
  317. return m_lLastError;
  318. }
  319.  
  320. LONG CSerial::Setup (EBaudrate eBaudrate, EDataBits eDataBits, EParity eParity, EStopBits eStopBits)
  321. {
  322. // Reset error state
  323. m_lLastError = ERROR_SUCCESS;
  324.  
  325. // Check if the device is open
  326. if (m_hFile == 0)
  327. {
  328. // Set the internal error code
  329. m_lLastError = ERROR_INVALID_HANDLE;
  330.  
  331. // Issue an error and quit
  332. _RPTF0(_CRT_WARN,"CSerial::Setup - Device is not opened\n");
  333. return m_lLastError;
  334. }
  335.  
  336. // Obtain the DCB structure for the device
  337. CDCB dcb;
  338. if (!::GetCommState(m_hFile,&dcb))
  339. {
  340. // Obtain the error code
  341. m_lLastError = :: GetLastError();
  342.  
  343. // Display a warning
  344. _RPTF0(_CRT_WARN,"CSerial::Setup - Unable to obtain DCB information\n");
  345. return m_lLastError;
  346. }
  347.  
  348. // Set the new data
  349. dcb.BaudRate = DWORD(eBaudrate);
  350. dcb.ByteSize = BYTE(eDataBits);
  351. dcb.Parity = BYTE(eParity);
  352. dcb.StopBits = BYTE(eStopBits);
  353.  
  354. // Determine if parity is used
  355. dcb.fParity = (eParity != EParNone);
  356.  
  357. // Set the new DCB structure
  358. if (!::SetCommState(m_hFile,&dcb))
  359. {
  360. // Obtain the error code
  361. m_lLastError = ::GetLastError();
  362.  
  363. // Display a warning
  364. _RPTF0(_CRT_WARN,"CSerial::Setup - Unable to set DCB information\n");
  365. return m_lLastError;
  366. }
  367.  
  368. // Return successful
  369. return m_lLastError;
  370. }
  371.  
  372. LONG CSerial::SetEventChar (BYTE bEventChar, bool fAdjustMask)
  373. {
  374. // Reset error state
  375. m_lLastError = ERROR_SUCCESS;
  376.  
  377. // Check if the device is open
  378. if (m_hFile == 0)
  379. {
  380. // Set the internal error code
  381. m_lLastError = ERROR_INVALID_HANDLE;
  382.  
  383. // Issue an error and quit
  384. _RPTF0(_CRT_WARN,"CSerial::SetEventChar - Device is not opened\n");
  385. return m_lLastError;
  386. }
  387.  
  388. // Obtain the DCB structure for the device
  389. CDCB dcb;
  390. if (!::GetCommState(m_hFile,&dcb))
  391. {
  392. // Obtain the error code
  393. m_lLastError = ::GetLastError();
  394.  
  395. // Display a warning
  396. _RPTF0(_CRT_WARN,"CSerial::SetEventChar - Unable to obtain DCB information\n");
  397. return m_lLastError;
  398. }
  399.  
  400. // Set the new event character
  401. dcb.EvtChar = char(bEventChar);
  402.  
  403. // Adjust the event mask, to make sure the event will be received
  404. if (fAdjustMask)
  405. {
  406. // Enable 'receive event character' event. Note that this
  407. // will generate an EEventNone if there is an asynchronous
  408. // WaitCommEvent pending.
  409. SetMask(GetEventMask() | EEventRcvEv);
  410. }
  411.  
  412. // Set the new DCB structure
  413. if (!::SetCommState(m_hFile,&dcb))
  414. {
  415. // Obtain the error code
  416. m_lLastError = ::GetLastError();
  417.  
  418. // Display a warning
  419. _RPTF0(_CRT_WARN,"CSerial::SetEventChar - Unable to set DCB information\n");
  420. return m_lLastError;
  421. }
  422.  
  423. // Return successful
  424. return m_lLastError;
  425. }
  426.  
  427. LONG CSerial::SetMask (DWORD dwEventMask)
  428. {
  429. // Reset error state
  430. m_lLastError = ERROR_SUCCESS;
  431.  
  432. // Check if the device is open
  433. if (m_hFile == 0)
  434. {
  435. // Set the internal error code
  436. m_lLastError = ERROR_INVALID_HANDLE;
  437.  
  438. // Issue an error and quit
  439. _RPTF0(_CRT_WARN,"CSerial::SetMask - Device is not opened\n");
  440. return m_lLastError;
  441. }
  442.  
  443. // Set the new mask. Note that this will generate an EEventNone
  444. // if there is an asynchronous WaitCommEvent pending.
  445. if (!::SetCommMask(m_hFile,dwEventMask))
  446. {
  447. // Obtain the error code
  448. m_lLastError = ::GetLastError();
  449.  
  450. // Display a warning
  451. _RPTF0(_CRT_WARN,"CSerial::SetMask - Unable to set event mask\n");
  452. return m_lLastError;
  453. }
  454.  
  455. // Save event mask and return successful
  456. m_dwEventMask = dwEventMask;
  457. return m_lLastError;
  458. }
  459.  
  460. LONG CSerial::WaitEvent (LPOVERLAPPED lpOverlapped, DWORD dwTimeout)
  461. {
  462. // Check if time-outs are supported
  463. CheckRequirements(lpOverlapped,dwTimeout);
  464.  
  465. // Reset error state
  466. m_lLastError = ERROR_SUCCESS;
  467.  
  468. // Check if the device is open
  469. if (m_hFile == 0)
  470. {
  471. // Set the internal error code
  472. m_lLastError = ERROR_INVALID_HANDLE;
  473.  
  474. // Issue an error and quit
  475. _RPTF0(_CRT_WARN,"CSerial::WaitEvent - Device is not opened\n");
  476. return m_lLastError;
  477. }
  478.  
  479. #ifndef SERIAL_NO_OVERLAPPED
  480.  
  481. // Check if an overlapped structure has been specified
  482. if (!m_hevtOverlapped && (lpOverlapped || (dwTimeout != INFINITE)))
  483. {
  484. // Set the internal error code
  485. m_lLastError = ERROR_INVALID_FUNCTION;
  486.  
  487. // Issue an error and quit
  488. _RPTF0(_CRT_WARN,"CSerial::WaitEvent - Overlapped I/O is disabled, specified parameters are illegal.\n");
  489. return m_lLastError;
  490. }
  491.  
  492. // Wait for the event to happen
  493. OVERLAPPED ovInternal;
  494. if (!lpOverlapped && m_hevtOverlapped)
  495. {
  496. // Setup our own overlapped structure
  497. memset(&ovInternal,0,sizeof(ovInternal));
  498. ovInternal.hEvent = m_hevtOverlapped;
  499.  
  500. // Use our internal overlapped structure
  501. lpOverlapped = &ovInternal;
  502. }
  503.  
  504. // Make sure the overlapped structure isn't busy
  505. _ASSERTE(!m_hevtOverlapped || HasOverlappedIoCompleted(lpOverlapped));
  506.  
  507. // Wait for the COM event
  508. if (!::WaitCommEvent(m_hFile,LPDWORD(&m_eEvent),lpOverlapped))
  509. {
  510. // Set the internal error code
  511. long lLastError = ::GetLastError();
  512.  
  513. // Overlapped operation in progress is not an actual error
  514. if (lLastError != ERROR_IO_PENDING)
  515. {
  516. // Save the error
  517. m_lLastError = lLastError;
  518.  
  519. // Issue an error and quit
  520. _RPTF0(_CRT_WARN,"CSerial::WaitEvent - Unable to wait for COM event\n");
  521. return m_lLastError;
  522. }
  523.  
  524. // We need to block if the client didn't specify an overlapped structure
  525. if (lpOverlapped == &ovInternal)
  526. {
  527. // Wait for the overlapped operation to complete
  528. switch (::WaitForSingleObject(lpOverlapped->hEvent,dwTimeout))
  529. {
  530. case WAIT_OBJECT_0:
  531. // The overlapped operation has completed
  532. break;
  533.  
  534. case WAIT_TIMEOUT:
  535. // Cancel the I/O operation
  536. CancelCommIo();
  537.  
  538. // The operation timed out. Set the internal error code and quit
  539. m_lLastError = ERROR_TIMEOUT;
  540. return m_lLastError;
  541.  
  542. default:
  543. // Set the internal error code
  544. m_lLastError = ::GetLastError();
  545.  
  546. // Issue an error and quit
  547. _RPTF0(_CRT_WARN,"CSerial::WaitEvent - Unable to wait until COM event has arrived\n");
  548. return m_lLastError;
  549. }
  550. }
  551. }
  552. else
  553. {
  554. // The operation completed immediatly. Just to be sure
  555. // we'll set the overlapped structure's event handle.
  556. if (lpOverlapped)
  557. ::SetEvent(lpOverlapped->hEvent);
  558. }
  559. #else
  560.  
  561. // Wait for the COM event
  562. if (!::WaitCommEvent(m_hFile,LPDWORD(&m_eEvent),0))
  563. {
  564. // Set the internal error code
  565. m_lLastError = ::GetLastError();
  566.  
  567. // Issue an error and quit
  568. _RPTF0(_CRT_WARN,"CSerial::WaitEvent - Unable to wait for COM event\n");
  569. return m_lLastError;
  570. }
  571.  
  572. #endif
  573.  
  574. // Return successfully
  575. return m_lLastError;
  576. }
  577.  
  578.  
  579. LONG CSerial::SetupHandshaking (EHandshake eHandshake)
  580. {
  581. // Reset error state
  582. m_lLastError = ERROR_SUCCESS;
  583.  
  584. // Check if the device is open
  585. if (m_hFile == 0)
  586. {
  587. // Set the internal error code
  588. m_lLastError = ERROR_INVALID_HANDLE;
  589.  
  590. // Issue an error and quit
  591. _RPTF0(_CRT_WARN,"CSerial::SetupHandshaking - Device is not opened\n");
  592. return m_lLastError;
  593. }
  594.  
  595. // Obtain the DCB structure for the device
  596. CDCB dcb;
  597. if (!::GetCommState(m_hFile,&dcb))
  598. {
  599. // Obtain the error code
  600. m_lLastError = ::GetLastError();
  601.  
  602. // Display a warning
  603. _RPTF0(_CRT_WARN,"CSerial::SetupHandshaking - Unable to obtain DCB information\n");
  604. return m_lLastError;
  605. }
  606.  
  607. // Set the handshaking flags
  608. switch (eHandshake)
  609. {
  610. case EHandshakeOff:
  611. dcb.fOutxCtsFlow = false; // Disable CTS monitoring
  612. dcb.fOutxDsrFlow = false; // Disable DSR monitoring
  613. dcb.fDtrControl = DTR_CONTROL_DISABLE; // Disable DTR monitoring
  614. dcb.fOutX = false; // Disable XON/XOFF for transmission
  615. dcb.fInX = false; // Disable XON/XOFF for receiving
  616. dcb.fRtsControl = RTS_CONTROL_DISABLE; // Disable RTS (Ready To Send)
  617. break;
  618.  
  619. case EHandshakeHardware:
  620. dcb.fOutxCtsFlow = true; // Enable CTS monitoring
  621. dcb.fOutxDsrFlow = true; // Enable DSR monitoring
  622. dcb.fDtrControl = DTR_CONTROL_HANDSHAKE; // Enable DTR handshaking
  623. dcb.fOutX = false; // Disable XON/XOFF for transmission
  624. dcb.fInX = false; // Disable XON/XOFF for receiving
  625. dcb.fRtsControl = RTS_CONTROL_HANDSHAKE; // Enable RTS handshaking
  626. break;
  627.  
  628. case EHandshakeSoftware:
  629. dcb.fOutxCtsFlow = false; // Disable CTS (Clear To Send)
  630. dcb.fOutxDsrFlow = false; // Disable DSR (Data Set Ready)
  631. dcb.fDtrControl = DTR_CONTROL_DISABLE; // Disable DTR (Data Terminal Ready)
  632. dcb.fOutX = true; // Enable XON/XOFF for transmission
  633. dcb.fInX = true; // Enable XON/XOFF for receiving
  634. dcb.fRtsControl = RTS_CONTROL_DISABLE; // Disable RTS (Ready To Send)
  635. break;
  636.  
  637. default:
  638. // This shouldn't be possible
  639. _ASSERTE(false);
  640. m_lLastError = E_INVALIDARG;
  641. return m_lLastError;
  642. }
  643.  
  644. // Set the new DCB structure
  645. if (!::SetCommState(m_hFile,&dcb))
  646. {
  647. // Obtain the error code
  648. m_lLastError = ::GetLastError();
  649.  
  650. // Display a warning
  651. _RPTF0(_CRT_WARN,"CSerial::SetupHandshaking - Unable to set DCB information\n");
  652. return m_lLastError;
  653. }
  654.  
  655. // Return successful
  656. return m_lLastError;
  657. }
  658.  
  659. LONG CSerial::SetupReadTimeouts (EReadTimeout eReadTimeout)
  660. {
  661. // Reset error state
  662. m_lLastError = ERROR_SUCCESS;
  663.  
  664. // Check if the device is open
  665. if (m_hFile == 0)
  666. {
  667. // Set the internal error code
  668. m_lLastError = ERROR_INVALID_HANDLE;
  669.  
  670. // Issue an error and quit
  671. _RPTF0(_CRT_WARN,"CSerial::SetupReadTimeouts - Device is not opened\n");
  672. return m_lLastError;
  673. }
  674.  
  675. // Determine the time-outs
  676. COMMTIMEOUTS cto;
  677. if (!::GetCommTimeouts(m_hFile,&cto))
  678. {
  679. // Obtain the error code
  680. m_lLastError = ::GetLastError();
  681.  
  682. // Display a warning
  683. _RPTF0(_CRT_WARN,"CSerial::SetupReadTimeouts - Unable to obtain timeout information\n");
  684. return m_lLastError;
  685. }
  686.  
  687. // Set the new timeouts
  688. switch (eReadTimeout)
  689. {
  690. case EReadTimeoutBlocking:
  691. cto.ReadIntervalTimeout = 0;
  692. cto.ReadTotalTimeoutConstant = 0;
  693. cto.ReadTotalTimeoutMultiplier = 0;
  694. break;
  695. case EReadTimeoutNonblocking:
  696. cto.ReadIntervalTimeout = MAXDWORD;
  697. cto.ReadTotalTimeoutConstant = 0;
  698. cto.ReadTotalTimeoutMultiplier = 0;
  699. break;
  700. default:
  701. // This shouldn't be possible
  702. _ASSERTE(false);
  703. m_lLastError = E_INVALIDARG;
  704. return m_lLastError;
  705. }
  706.  
  707. // Set the new DCB structure
  708. if (!::SetCommTimeouts(m_hFile,&cto))
  709. {
  710. // Obtain the error code
  711. m_lLastError = ::GetLastError();
  712.  
  713. // Display a warning
  714. _RPTF0(_CRT_WARN,"CSerial::SetupReadTimeouts - Unable to set timeout information\n");
  715. return m_lLastError;
  716. }
  717.  
  718. // Return successful
  719. return m_lLastError;
  720. }
  721.  
  722. CSerial::EBaudrate CSerial::GetBaudrate (void)
  723. {
  724. // Reset error state
  725. m_lLastError = ERROR_SUCCESS;
  726.  
  727. // Check if the device is open
  728. if (m_hFile == 0)
  729. {
  730. // Set the internal error code
  731. m_lLastError = ERROR_INVALID_HANDLE;
  732.  
  733. // Issue an error and quit
  734. _RPTF0(_CRT_WARN,"CSerial::GetBaudrate - Device is not opened\n");
  735. return EBaudUnknown;
  736. }
  737.  
  738. // Obtain the DCB structure for the device
  739. CDCB dcb;
  740. if (!::GetCommState(m_hFile,&dcb))
  741. {
  742. // Obtain the error code
  743. m_lLastError = ::GetLastError();
  744.  
  745. // Display a warning
  746. _RPTF0(_CRT_WARN,"CSerial::GetBaudrate - Unable to obtain DCB information\n");
  747. return EBaudUnknown;
  748. }
  749.  
  750. // Return the appropriate baudrate
  751. return EBaudrate(dcb.BaudRate);
  752. }
  753.  
  754. CSerial::EDataBits CSerial::GetDataBits (void)
  755. {
  756. // Reset error state
  757. m_lLastError = ERROR_SUCCESS;
  758.  
  759. // Check if the device is open
  760. if (m_hFile == 0)
  761. {
  762. // Set the internal error code
  763. m_lLastError = ERROR_INVALID_HANDLE;
  764.  
  765. // Issue an error and quit
  766. _RPTF0(_CRT_WARN,"CSerial::GetDataBits - Device is not opened\n");
  767. return EDataUnknown;
  768. }
  769.  
  770. // Obtain the DCB structure for the device
  771. CDCB dcb;
  772. if (!::GetCommState(m_hFile,&dcb))
  773. {
  774. // Obtain the error code
  775. m_lLastError = ::GetLastError();
  776.  
  777. // Display a warning
  778. _RPTF0(_CRT_WARN,"CSerial::GetDataBits - Unable to obtain DCB information\n");
  779. return EDataUnknown;
  780. }
  781.  
  782. // Return the appropriate bytesize
  783. return EDataBits(dcb.ByteSize);
  784. }
  785.  
  786. CSerial::EParity CSerial::GetParity (void)
  787. {
  788. // Reset error state
  789. m_lLastError = ERROR_SUCCESS;
  790.  
  791. // Check if the device is open
  792. if (m_hFile == 0)
  793. {
  794. // Set the internal error code
  795. m_lLastError = ERROR_INVALID_HANDLE;
  796.  
  797. // Issue an error and quit
  798. _RPTF0(_CRT_WARN,"CSerial::GetParity - Device is not opened\n");
  799. return EParUnknown;
  800. }
  801.  
  802. // Obtain the DCB structure for the device
  803. CDCB dcb;
  804. if (!::GetCommState(m_hFile,&dcb))
  805. {
  806. // Obtain the error code
  807. m_lLastError = ::GetLastError();
  808.  
  809. // Display a warning
  810. _RPTF0(_CRT_WARN,"CSerial::GetParity - Unable to obtain DCB information\n");
  811. return EParUnknown;
  812. }
  813.  
  814. // Check if parity is used
  815. if (!dcb.fParity)
  816. {
  817. // No parity
  818. return EParNone;
  819. }
  820.  
  821. // Return the appropriate parity setting
  822. return EParity(dcb.Parity);
  823. }
  824.  
  825. CSerial::EStopBits CSerial::GetStopBits (void)
  826. {
  827. // Reset error state
  828. m_lLastError = ERROR_SUCCESS;
  829.  
  830. // Check if the device is open
  831. if (m_hFile == 0)
  832. {
  833. // Set the internal error code
  834. m_lLastError = ERROR_INVALID_HANDLE;
  835.  
  836. // Issue an error and quit
  837. _RPTF0(_CRT_WARN,"CSerial::GetStopBits - Device is not opened\n");
  838. return EStopUnknown;
  839. }
  840.  
  841. // Obtain the DCB structure for the device
  842. CDCB dcb;
  843. if (!::GetCommState(m_hFile,&dcb))
  844. {
  845. // Obtain the error code
  846. m_lLastError = ::GetLastError();
  847.  
  848. // Display a warning
  849. _RPTF0(_CRT_WARN,"CSerial::GetStopBits - Unable to obtain DCB information\n");
  850. return EStopUnknown;
  851. }
  852.  
  853. // Return the appropriate stopbits
  854. return EStopBits(dcb.StopBits);
  855. }
  856.  
  857. DWORD CSerial::GetEventMask (void)
  858. {
  859. // Reset error state
  860. m_lLastError = ERROR_SUCCESS;
  861.  
  862. // Check if the device is open
  863. if (m_hFile == 0)
  864. {
  865. // Set the internal error code
  866. m_lLastError = ERROR_INVALID_HANDLE;
  867.  
  868. // Issue an error and quit
  869. _RPTF0(_CRT_WARN,"CSerial::GetEventMask - Device is not opened\n");
  870. return 0;
  871. }
  872.  
  873. // Return the event mask
  874. return m_dwEventMask;
  875. }
  876.  
  877. BYTE CSerial::GetEventChar (void)
  878. {
  879. // Reset error state
  880. m_lLastError = ERROR_SUCCESS;
  881.  
  882. // Check if the device is open
  883. if (m_hFile == 0)
  884. {
  885. // Set the internal error code
  886. m_lLastError = ERROR_INVALID_HANDLE;
  887.  
  888. // Issue an error and quit
  889. _RPTF0(_CRT_WARN,"CSerial::GetEventChar - Device is not opened\n");
  890. return 0;
  891. }
  892.  
  893. // Obtain the DCB structure for the device
  894. CDCB dcb;
  895. if (!::GetCommState(m_hFile,&dcb))
  896. {
  897. // Obtain the error code
  898. m_lLastError = ::GetLastError();
  899.  
  900. // Display a warning
  901. _RPTF0(_CRT_WARN,"CSerial::GetEventChar - Unable to obtain DCB information\n");
  902. return 0;
  903. }
  904.  
  905. // Set the new event character
  906. return BYTE(dcb.EvtChar);
  907. }
  908.  
  909. CSerial::EHandshake CSerial::GetHandshaking (void)
  910. {
  911. // Reset error state
  912. m_lLastError = ERROR_SUCCESS;
  913.  
  914. // Check if the device is open
  915. if (m_hFile == 0)
  916. {
  917. // Set the internal error code
  918. m_lLastError = ERROR_INVALID_HANDLE;
  919.  
  920. // Issue an error and quit
  921. _RPTF0(_CRT_WARN,"CSerial::GetHandshaking - Device is not opened\n");
  922. return EHandshakeUnknown;
  923. }
  924.  
  925. // Obtain the DCB structure for the device
  926. CDCB dcb;
  927. if (!::GetCommState(m_hFile,&dcb))
  928. {
  929. // Obtain the error code
  930. m_lLastError = ::GetLastError();
  931.  
  932. // Display a warning
  933. _RPTF0(_CRT_WARN,"CSerial::GetHandshaking - Unable to obtain DCB information\n");
  934. return EHandshakeUnknown;
  935. }
  936.  
  937. // Check if hardware handshaking is being used
  938. if ((dcb.fDtrControl == DTR_CONTROL_HANDSHAKE) && (dcb.fRtsControl == RTS_CONTROL_HANDSHAKE))
  939. return EHandshakeHardware;
  940.  
  941. // Check if software handshaking is being used
  942. if (dcb.fOutX && dcb.fInX)
  943. return EHandshakeSoftware;
  944.  
  945. // No handshaking is being used
  946. return EHandshakeOff;
  947. }
  948.  
  949. LONG CSerial::Write (const void* pData, size_t iLen, DWORD* pdwWritten, LPOVERLAPPED lpOverlapped, DWORD dwTimeout)
  950. {
  951. // Check if time-outs are supported
  952. CheckRequirements(lpOverlapped,dwTimeout);
  953.  
  954. // Overlapped operation should specify the pdwWritten variable
  955. _ASSERTE(!lpOverlapped || pdwWritten);
  956.  
  957. // Reset error state
  958. m_lLastError = ERROR_SUCCESS;
  959.  
  960. // Use our own variable for read count
  961. DWORD dwWritten;
  962. if (pdwWritten == 0)
  963. {
  964. pdwWritten = &dwWritten;
  965. }
  966.  
  967. // Reset the number of bytes written
  968. *pdwWritten = 0;
  969.  
  970. // Check if the device is open
  971. if (m_hFile == 0)
  972. {
  973. // Set the internal error code
  974. m_lLastError = ERROR_INVALID_HANDLE;
  975.  
  976. // Issue an error and quit
  977. _RPTF0(_CRT_WARN,"CSerial::Write - Device is not opened\n");
  978. return m_lLastError;
  979. }
  980.  
  981. #ifndef SERIAL_NO_OVERLAPPED
  982.  
  983. // Check if an overlapped structure has been specified
  984. if (!m_hevtOverlapped && (lpOverlapped || (dwTimeout != INFINITE)))
  985. {
  986. // Set the internal error code
  987. m_lLastError = ERROR_INVALID_FUNCTION;
  988.  
  989. // Issue an error and quit
  990. _RPTF0(_CRT_WARN,"CSerial::Write - Overlapped I/O is disabled, specified parameters are illegal.\n");
  991. return m_lLastError;
  992. }
  993.  
  994. // Wait for the event to happen
  995. OVERLAPPED ovInternal;
  996. if (!lpOverlapped && m_hevtOverlapped)
  997. {
  998. // Setup our own overlapped structure
  999. memset(&ovInternal,0,sizeof(ovInternal));
  1000. ovInternal.hEvent = m_hevtOverlapped;
  1001.  
  1002. // Use our internal overlapped structure
  1003. lpOverlapped = &ovInternal;
  1004. }
  1005.  
  1006. // Make sure the overlapped structure isn't busy
  1007. _ASSERTE(!m_hevtOverlapped || HasOverlappedIoCompleted(lpOverlapped));
  1008.  
  1009. // Write the data
  1010. if (!::WriteFile(m_hFile,pData,iLen,pdwWritten,lpOverlapped))
  1011. {
  1012. // Set the internal error code
  1013. long lLastError = ::GetLastError();
  1014.  
  1015. // Overlapped operation in progress is not an actual error
  1016. if (lLastError != ERROR_IO_PENDING)
  1017. {
  1018. // Save the error
  1019. m_lLastError = lLastError;
  1020.  
  1021. // Issue an error and quit
  1022. _RPTF0(_CRT_WARN,"CSerial::Write - Unable to write the data\n");
  1023. return m_lLastError;
  1024. }
  1025.  
  1026. // We need to block if the client didn't specify an overlapped structure
  1027. if (lpOverlapped == &ovInternal)
  1028. {
  1029. // Wait for the overlapped operation to complete
  1030. switch (::WaitForSingleObject(lpOverlapped->hEvent,dwTimeout))
  1031. {
  1032. case WAIT_OBJECT_0:
  1033. // The overlapped operation has completed
  1034. if (!::GetOverlappedResult(m_hFile,lpOverlapped,pdwWritten,FALSE))
  1035. {
  1036. // Set the internal error code
  1037. m_lLastError = ::GetLastError();
  1038.  
  1039. _RPTF0(_CRT_WARN,"CSerial::Write - Overlapped completed without result\n");
  1040. return m_lLastError;
  1041. }
  1042. break;
  1043.  
  1044. case WAIT_TIMEOUT:
  1045. // Cancel the I/O operation
  1046. CancelCommIo();
  1047.  
  1048. // The operation timed out. Set the internal error code and quit
  1049. m_lLastError = ERROR_TIMEOUT;
  1050. return m_lLastError;
  1051.  
  1052. default:
  1053. // Set the internal error code
  1054. m_lLastError = ::GetLastError();
  1055.  
  1056. // Issue an error and quit
  1057. _RPTF0(_CRT_WARN,"CSerial::Write - Unable to wait until data has been sent\n");
  1058. return m_lLastError;
  1059. }
  1060. }
  1061. }
  1062. else
  1063. {
  1064. // The operation completed immediatly. Just to be sure
  1065. // we'll set the overlapped structure's event handle.
  1066. if (lpOverlapped)
  1067. ::SetEvent(lpOverlapped->hEvent);
  1068. }
  1069.  
  1070. #else
  1071.  
  1072. // Write the data
  1073. if (!::WriteFile(m_hFile,pData,iLen,pdwWritten,0))
  1074. {
  1075. // Set the internal error code
  1076. m_lLastError = ::GetLastError();
  1077.  
  1078. // Issue an error and quit
  1079. _RPTF0(_CRT_WARN,"CSerial::Write - Unable to write the data\n");
  1080. return m_lLastError;
  1081. }
  1082.  
  1083. #endif
  1084.  
  1085. // Return successfully
  1086. return m_lLastError;
  1087. }
  1088.  
  1089. LONG CSerial::Write (LPCSTR pString, DWORD* pdwWritten, LPOVERLAPPED lpOverlapped, DWORD dwTimeout)
  1090. {
  1091. // Check if time-outs are supported
  1092. CheckRequirements(lpOverlapped,dwTimeout);
  1093.  
  1094. // Determine the length of the string
  1095. return Write(pString,strlen(pString),pdwWritten,lpOverlapped,dwTimeout);
  1096. }
  1097.  
  1098. LONG CSerial::Read (void* pData, size_t iLen, DWORD* pdwRead, LPOVERLAPPED lpOverlapped, DWORD dwTimeout)
  1099. {
  1100. // Check if time-outs are supported
  1101. CheckRequirements(lpOverlapped,dwTimeout);
  1102.  
  1103. // Overlapped operation should specify the pdwRead variable
  1104. _ASSERTE(!lpOverlapped || pdwRead);
  1105.  
  1106. // Reset error state
  1107. m_lLastError = ERROR_SUCCESS;
  1108.  
  1109. // Use our own variable for read count
  1110. DWORD dwRead;
  1111. if (pdwRead == 0)
  1112. {
  1113. pdwRead = &dwRead;
  1114. }
  1115.  
  1116. // Reset the number of bytes read
  1117. *pdwRead = 0;
  1118.  
  1119. // Check if the device is open
  1120. if (m_hFile == 0)
  1121. {
  1122. // Set the internal error code
  1123. m_lLastError = ERROR_INVALID_HANDLE;
  1124.  
  1125. // Issue an error and quit
  1126. _RPTF0(_CRT_WARN,"CSerial::Read - Device is not opened\n");
  1127. return m_lLastError;
  1128. }
  1129.  
  1130. #ifdef _DEBUG
  1131. // The debug version fills the entire data structure with
  1132. // 0xDC bytes, to catch buffer errors as soon as possible.
  1133. memset(pData,0xDC,iLen);
  1134. #endif
  1135.  
  1136. #ifndef SERIAL_NO_OVERLAPPED
  1137.  
  1138. // Check if an overlapped structure has been specified
  1139. if (!m_hevtOverlapped && (lpOverlapped || (dwTimeout != INFINITE)))
  1140. {
  1141. // Set the internal error code
  1142. m_lLastError = ERROR_INVALID_FUNCTION;
  1143.  
  1144. // Issue an error and quit
  1145. _RPTF0(_CRT_WARN,"CSerial::Read - Overlapped I/O is disabled, specified parameters are illegal.\n");
  1146. return m_lLastError;
  1147. }
  1148.  
  1149. // Wait for the event to happen
  1150. OVERLAPPED ovInternal;
  1151. if (lpOverlapped == 0)
  1152. {
  1153. // Setup our own overlapped structure
  1154. memset(&ovInternal,0,sizeof(ovInternal));
  1155. ovInternal.hEvent = m_hevtOverlapped;
  1156.  
  1157. // Use our internal overlapped structure
  1158. lpOverlapped = &ovInternal;
  1159. }
  1160.  
  1161. // Make sure the overlapped structure isn't busy
  1162. _ASSERTE(!m_hevtOverlapped || HasOverlappedIoCompleted(lpOverlapped));
  1163.  
  1164. // Read the data
  1165. if (!::ReadFile(m_hFile,pData,iLen,pdwRead,lpOverlapped))
  1166. {
  1167. // Set the internal error code
  1168. long lLastError = ::GetLastError();
  1169.  
  1170. // Overlapped operation in progress is not an actual error
  1171. if (lLastError != ERROR_IO_PENDING)
  1172. {
  1173. // Save the error
  1174. m_lLastError = lLastError;
  1175.  
  1176. // Issue an error and quit
  1177. _RPTF0(_CRT_WARN,"CSerial::Read - Unable to read the data\n");
  1178. return m_lLastError;
  1179. }
  1180.  
  1181. // We need to block if the client didn't specify an overlapped structure
  1182. if (lpOverlapped == &ovInternal)
  1183. {
  1184. // Wait for the overlapped operation to complete
  1185. switch (::WaitForSingleObject(lpOverlapped->hEvent,dwTimeout))
  1186. {
  1187. case WAIT_OBJECT_0:
  1188. // The overlapped operation has completed
  1189. if (!::GetOverlappedResult(m_hFile,lpOverlapped,pdwRead,FALSE))
  1190. {
  1191. // Set the internal error code
  1192. m_lLastError = ::GetLastError();
  1193.  
  1194. _RPTF0(_CRT_WARN,"CSerial::Read - Overlapped completed without result\n");
  1195. return m_lLastError;
  1196. }
  1197. break;
  1198.  
  1199. case WAIT_TIMEOUT:
  1200. // Cancel the I/O operation
  1201. CancelCommIo();
  1202.  
  1203. // The operation timed out. Set the internal error code and quit
  1204. m_lLastError = ERROR_TIMEOUT;
  1205. return m_lLastError;
  1206.  
  1207. default:
  1208. // Set the internal error code
  1209. m_lLastError = ::GetLastError();
  1210.  
  1211. // Issue an error and quit
  1212. _RPTF0(_CRT_WARN,"CSerial::Read - Unable to wait until data has been read\n");
  1213. return m_lLastError;
  1214. }
  1215. }
  1216. }
  1217. else
  1218. {
  1219. // The operation completed immediatly. Just to be sure
  1220. // we'll set the overlapped structure's event handle.
  1221. if (lpOverlapped)
  1222. ::SetEvent(lpOverlapped->hEvent);
  1223. }
  1224.  
  1225. #else
  1226.  
  1227. // Read the data
  1228. if (!::ReadFile(m_hFile,pData,iLen,pdwRead,0))
  1229. {
  1230. // Set the internal error code
  1231. m_lLastError = ::GetLastError();
  1232.  
  1233. // Issue an error and quit
  1234. _RPTF0(_CRT_WARN,"CSerial::Read - Unable to read the data\n");
  1235. return m_lLastError;
  1236. }
  1237.  
  1238. #endif
  1239.  
  1240. // Return successfully
  1241. return m_lLastError;
  1242. }
  1243.  
  1244. LONG CSerial::Purge()
  1245. {
  1246. // Reset error state
  1247. m_lLastError = ERROR_SUCCESS;
  1248.  
  1249. // Check if the device is open
  1250. if (m_hFile == 0)
  1251. {
  1252. // Set the internal error code
  1253. m_lLastError = ERROR_INVALID_HANDLE;
  1254.  
  1255. // Issue an error and quit
  1256. _RPTF0(_CRT_WARN,"CSerial::Purge - Device is not opened\n");
  1257. return m_lLastError;
  1258. }
  1259.  
  1260. if (!::PurgeComm(m_hFile, PURGE_TXCLEAR | PURGE_RXCLEAR))
  1261. {
  1262. // Set the internal error code
  1263. m_lLastError = ::GetLastError();
  1264. _RPTF0(_CRT_WARN,"CSerial::Purge - Overlapped completed without result\n");
  1265. }
  1266.  
  1267. // Return successfully
  1268. return m_lLastError;
  1269. }
  1270.  
  1271. LONG CSerial::Break (void)
  1272. {
  1273. // Reset error state
  1274. m_lLastError = ERROR_SUCCESS;
  1275.  
  1276. // Check if the device is open
  1277. if (m_hFile == 0)
  1278. {
  1279. // Set the internal error code
  1280. m_lLastError = ERROR_INVALID_HANDLE;
  1281.  
  1282. // Issue an error and quit
  1283. _RPTF0(_CRT_WARN,"CSerial::Break - Device is not opened\n");
  1284. return m_lLastError;
  1285. }
  1286.  
  1287. // Set the RS-232 port in break mode for a little while
  1288. ::SetCommBreak(m_hFile);
  1289. ::Sleep(100);
  1290. ::ClearCommBreak(m_hFile);
  1291.  
  1292. // Return successfully
  1293. return m_lLastError;
  1294. }
  1295.  
  1296. CSerial::EEvent CSerial::GetEventType (void)
  1297. {
  1298. #ifdef _DEBUG
  1299. // Check if the event is within the mask
  1300. if ((m_eEvent & m_dwEventMask) == 0)
  1301. _RPTF2(_CRT_WARN,"CSerial::GetEventType - Event %08Xh not within mask %08Xh.\n", m_eEvent, m_dwEventMask);
  1302. #endif
  1303.  
  1304. // Obtain the event (mask unwanted events out)
  1305. EEvent eEvent = EEvent(m_eEvent & m_dwEventMask);
  1306.  
  1307. // Reset internal event type
  1308. m_eEvent = EEventNone;
  1309.  
  1310. // Return the current cause
  1311. return eEvent;
  1312. }
  1313.  
  1314. CSerial::EError CSerial::GetError (void)
  1315. {
  1316. // Reset error state
  1317. m_lLastError = ERROR_SUCCESS;
  1318.  
  1319. // Check if the device is open
  1320. if (m_hFile == 0)
  1321. {
  1322. // Set the internal error code
  1323. m_lLastError = ERROR_INVALID_HANDLE;
  1324.  
  1325. // Issue an error and quit
  1326. _RPTF0(_CRT_WARN,"CSerial::GetError - Device is not opened\n");
  1327. return EErrorUnknown;
  1328. }
  1329.  
  1330. // Obtain COM status
  1331. DWORD dwErrors = 0;
  1332. if (!::ClearCommError(m_hFile,&dwErrors,0))
  1333. {
  1334. // Set the internal error code
  1335. m_lLastError = ::GetLastError();
  1336.  
  1337. // Issue an error and quit
  1338. _RPTF0(_CRT_WARN,"CSerial::GetError - Unable to obtain COM status\n");
  1339. return EErrorUnknown;
  1340. }
  1341.  
  1342. // Return the error
  1343. return EError(dwErrors);
  1344. }
  1345.  
  1346. bool CSerial::GetCTS (void)
  1347. {
  1348. // Reset error state
  1349. m_lLastError = ERROR_SUCCESS;
  1350.  
  1351. // Obtain the modem status
  1352. DWORD dwModemStat = 0;
  1353. if (!::GetCommModemStatus(m_hFile,&dwModemStat))
  1354. {
  1355. // Obtain the error code
  1356. m_lLastError = ::GetLastError();
  1357.  
  1358. // Display a warning
  1359. _RPTF0(_CRT_WARN,"CSerial::GetCTS - Unable to obtain the modem status\n");
  1360. return false;
  1361. }
  1362.  
  1363. // Determine if CTS is on
  1364. return (dwModemStat & MS_CTS_ON) != 0;
  1365. }
  1366.  
  1367. bool CSerial::GetDSR (void)
  1368. {
  1369. // Reset error state
  1370. m_lLastError = ERROR_SUCCESS;
  1371.  
  1372. // Obtain the modem status
  1373. DWORD dwModemStat = 0;
  1374. if (!::GetCommModemStatus(m_hFile,&dwModemStat))
  1375. {
  1376. // Obtain the error code
  1377. m_lLastError = ::GetLastError();
  1378.  
  1379. // Display a warning
  1380. _RPTF0(_CRT_WARN,"CSerial::GetDSR - Unable to obtain the modem status\n");
  1381. return false;
  1382. }
  1383.  
  1384. // Determine if DSR is on
  1385. return (dwModemStat & MS_DSR_ON) != 0;
  1386. }
  1387.  
  1388. bool CSerial::GetRing (void)
  1389. {
  1390. // Reset error state
  1391. m_lLastError = ERROR_SUCCESS;
  1392.  
  1393. // Obtain the modem status
  1394. DWORD dwModemStat = 0;
  1395. if (!::GetCommModemStatus(m_hFile,&dwModemStat))
  1396. {
  1397. // Obtain the error code
  1398. m_lLastError = ::GetLastError();
  1399.  
  1400. // Display a warning
  1401. _RPTF0(_CRT_WARN,"CSerial::GetRing - Unable to obtain the modem status");
  1402. return false;
  1403. }
  1404.  
  1405. // Determine if Ring is on
  1406. return (dwModemStat & MS_RING_ON) != 0;
  1407. }
  1408.  
  1409. bool CSerial::GetRLSD (void)
  1410. {
  1411. // Reset error state
  1412. m_lLastError = ERROR_SUCCESS;
  1413.  
  1414. // Obtain the modem status
  1415. DWORD dwModemStat = 0;
  1416. if (!::GetCommModemStatus(m_hFile,&dwModemStat))
  1417. {
  1418. // Obtain the error code
  1419. m_lLastError = ::GetLastError();
  1420.  
  1421. // Display a warning
  1422. _RPTF0(_CRT_WARN,"CSerial::GetRLSD - Unable to obtain the modem status");
  1423. return false;
  1424. }
  1425.  
  1426. // Determine if RLSD is on
  1427. return (dwModemStat & MS_RLSD_ON) != 0;
  1428. }
  1. // Serial.h - Definition of the CSerial class
  2. //
  3. // Copyright (C) 1999-2003 Ramon de Klein (Ramon.de.Klein@ict.nl)
  4. //
  5. // This library is free software; you can redistribute it and/or
  6. // modify it under the terms of the GNU Lesser General Public
  7. // License as published by the Free Software Foundation; either
  8. // version 2.1 of the License, or (at your option) any later version.
  9. //
  10. // This library is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. // Lesser General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU Lesser General Public
  16. // License along with this library; if not, write to the Free Software
  17. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18.  
  19.  
  20. #ifndef __SERIAL_H
  21. #define __SERIAL_H
  22.  
  23.  
  24. //////////////////////////////////////////////////////////////////////
  25. // The SERIAL_DEFAULT_OVERLAPPED defines if the default open mode uses
  26. // overlapped I/O. When overlapped I/O is available (normal Win32
  27. // platforms) it uses overlapped I/O. Windows CE doesn't allow the use
  28. // of overlapped I/O, so it is disabled there by default.
  29.  
  30. #ifndef SERIAL_DEFAULT_OVERLAPPED
  31. #ifndef SERIAL_NO_OVERLAPPED
  32. #define SERIAL_DEFAULT_OVERLAPPED true
  33. #else
  34. #define SERIAL_DEFAULT_OVERLAPPED false
  35. #endif
  36. #endif
  37.  
  38.  
  39. //////////////////////////////////////////////////////////////////////
  40. //
  41. // CSerial - Win32 wrapper for serial communications
  42. //
  43. // Serial communication often causes a lot of problems. This class
  44. // tries to supply an easy to use interface to deal with serial
  45. // devices.
  46. //
  47. // The class is actually pretty ease to use. You only need to open
  48. // the COM-port, where you need to specify the basic serial
  49. // communication parameters. You can also choose to setup handshaking
  50. // and read timeout behaviour.
  51. //
  52. // The following serial classes are available:
  53. //
  54. // CSerial - Serial communication support.
  55. // CSerialEx - Serial communication with listener thread for events
  56. // CSerialSync - Serial communication with synchronized event handler
  57. // CSerialWnd - Asynchronous serial support, which uses the Win32
  58. // message queue for event notification.
  59. // CSerialMFC - Preferred class to use in MFC-based GUI windows.
  60. //
  61. //
  62. // Pros:
  63. // -----
  64. // - Easy to use (hides a lot of nasty Win32 stuff)
  65. // - Fully ANSI and Unicode aware
  66. //
  67. // Cons:
  68. // -----
  69. // - Little less flexibility then native Win32 API, however you can
  70. // use this API at the same time for features which are missing
  71. // from this class.
  72. // - Incompatible with Windows 95 or Windows NT v3.51 (or earlier),
  73. // because CancelIo isn't support on these platforms. Define the
  74. // SERIAL_NO_CANCELIO macro for support of these platforms as
  75. // well. When this macro is defined, then only time-out values of
  76. // 0 or INFINITE are valid.
  77. //
  78. //
  79. // Copyright (C) 1999-2003 Ramon de Klein
  80. // (Ramon.de.Klein@ict.nl)
  81.  
  82. class CSerial
  83. {
  84. // Class enumerations
  85. public:
  86. // Communication event
  87. typedef enum
  88. {
  89. EEventUnknown = -1, // Unknown event
  90. EEventNone = 0, // Event trigged without cause
  91. EEventBreak = EV_BREAK, // A break was detected on input
  92. EEventCTS = EV_CTS, // The CTS signal changed state
  93. EEventDSR = EV_DSR, // The DSR signal changed state
  94. EEventError = EV_ERR, // A line-status error occurred
  95. EEventRing = EV_RING, // A ring indicator was detected
  96. EEventRLSD = EV_RLSD, // The RLSD signal changed state
  97. EEventRecv = EV_RXCHAR, // Data is received on input
  98. EEventRcvEv = EV_RXFLAG, // Event character was received on input
  99. EEventSend = EV_TXEMPTY, // Last character on output was sent
  100. EEventPrinterError = EV_PERR, // Printer error occured
  101. EEventRx80Full = EV_RX80FULL, // Receive buffer is 80 percent full
  102. EEventProviderEvt1 = EV_EVENT1, // Provider specific event 1
  103. EEventProviderEvt2 = EV_EVENT2, // Provider specific event 2
  104. }
  105. EEvent;
  106.  
  107. // Baudrate
  108. typedef enum
  109. {
  110. EBaudUnknown = -1, // Unknown
  111. EBaud110 = CBR_110, // 110 bits/sec
  112. EBaud300 = CBR_300, // 300 bits/sec
  113. EBaud600 = CBR_600, // 600 bits/sec
  114. EBaud1200 = CBR_1200, // 1200 bits/sec
  115. EBaud2400 = CBR_2400, // 2400 bits/sec
  116. EBaud4800 = CBR_4800, // 4800 bits/sec
  117. EBaud9600 = CBR_9600, // 9600 bits/sec
  118. EBaud14400 = CBR_14400, // 14400 bits/sec
  119. EBaud19200 = CBR_19200, // 19200 bits/sec (default)
  120. EBaud38400 = CBR_38400, // 38400 bits/sec
  121. EBaud56000 = CBR_56000, // 56000 bits/sec
  122. EBaud57600 = CBR_57600, // 57600 bits/sec
  123. EBaud115200 = CBR_115200, // 115200 bits/sec
  124. EBaud128000 = CBR_128000, // 128000 bits/sec
  125. EBaud256000 = CBR_256000, // 256000 bits/sec
  126. }
  127. EBaudrate;
  128.  
  129. // Data bits (5-8)
  130. typedef enum
  131. {
  132. EDataUnknown = -1, // Unknown
  133. EData5 = 5, // 5 bits per byte
  134. EData6 = 6, // 6 bits per byte
  135. EData7 = 7, // 7 bits per byte
  136. EData8 = 8 // 8 bits per byte (default)
  137. }
  138. EDataBits;
  139.  
  140. // Parity scheme
  141. typedef enum
  142. {
  143. EParUnknown = -1, // Unknown
  144. EParNone = NOPARITY, // No parity (default)
  145. EParOdd = ODDPARITY, // Odd parity
  146. EParEven = EVENPARITY, // Even parity
  147. EParMark = MARKPARITY, // Mark parity
  148. EParSpace = SPACEPARITY // Space parity
  149. }
  150. EParity;
  151.  
  152. // Stop bits
  153. typedef enum
  154. {
  155. EStopUnknown = -1, // Unknown
  156. EStop1 = ONESTOPBIT, // 1 stopbit (default)
  157. EStop1_5 = ONE5STOPBITS,// 1.5 stopbit
  158. EStop2 = TWOSTOPBITS // 2 stopbits
  159. }
  160. EStopBits;
  161.  
  162. // Handshaking
  163. typedef enum
  164. {
  165. EHandshakeUnknown = -1, // Unknown
  166. EHandshakeOff = 0, // No handshaking
  167. EHandshakeHardware = 1, // Hardware handshaking (RTS/CTS)
  168. EHandshakeSoftware = 2 // Software handshaking (XON/XOFF)
  169. }
  170. EHandshake;
  171.  
  172. // Timeout settings
  173. typedef enum
  174. {
  175. EReadTimeoutUnknown = -1, // Unknown
  176. EReadTimeoutNonblocking = 0, // Always return immediately
  177. EReadTimeoutBlocking = 1 // Block until everything is retrieved
  178. }
  179. EReadTimeout;
  180.  
  181. // Communication errors
  182. typedef enum
  183. {
  184. EErrorUnknown = 0, // Unknown
  185. EErrorBreak = CE_BREAK, // Break condition detected
  186. EErrorFrame = CE_FRAME, // Framing error
  187. EErrorIOE = CE_IOE, // I/O device error
  188. EErrorMode = CE_MODE, // Unsupported mode
  189. EErrorOverrun = CE_OVERRUN, // Character buffer overrun, next byte is lost
  190. EErrorRxOver = CE_RXOVER, // Input buffer overflow, byte lost
  191. EErrorParity = CE_RXPARITY,// Input parity error
  192. EErrorTxFull = CE_TXFULL // Output buffer full
  193. }
  194. EError;
  195.  
  196. // Port availability
  197. typedef enum
  198. {
  199. EPortUnknownError = -1, // Unknown error occurred
  200. EPortAvailable = 0, // Port is available
  201. EPortNotAvailable = 1, // Port is not present
  202. EPortInUse = 2 // Port is in use
  203.  
  204. }
  205. EPort;
  206.  
  207. // Construction
  208. public:
  209. CSerial();
  210. virtual ~CSerial();
  211.  
  212. // Operations
  213. public:
  214. // Check if particular COM-port is available (static method).
  215. static EPort CheckPort (LPCTSTR lpszDevice);
  216.  
  217. // Open the serial communications for a particular COM port. You
  218. // need to use the full devicename (i.e. "COM1") to open the port.
  219. // It's possible to specify the size of the input/output queues.
  220. virtual LONG Open (LPCTSTR lpszDevice, DWORD dwInQueue = 0, DWORD dwOutQueue = 0, bool fOverlapped = SERIAL_DEFAULT_OVERLAPPED);
  221.  
  222. // Close the serial port.
  223. virtual LONG Close (void);
  224.  
  225. // Setup the communication settings such as baudrate, databits,
  226. // parity and stopbits. The default settings are applied when the
  227. // device has been opened. Call this function if these settings do
  228. // not apply for your application. If you prefer to use integers
  229. // instead of the enumerated types then just cast the integer to
  230. // the required type. So the following two initializations are
  231. // equivalent:
  232. //
  233. // Setup(EBaud9600,EData8,EParNone,EStop1)
  234. //
  235. // or
  236. //
  237. // Setup(EBaudrate(9600),EDataBits(8),EParity(NOPARITY),EStopBits(ONESTOPBIT))
  238. //
  239. // In the latter case, the types are not validated. So make sure
  240. // that you specify the appropriate values.
  241. virtual LONG Setup (EBaudrate eBaudrate = EBaud9600,
  242. EDataBits eDataBits = EData8,
  243. EParity eParity = EParNone,
  244. EStopBits eStopBits = EStop1);
  245.  
  246. // Set/clear the event character. When this byte is being received
  247. // on the serial port then the EEventRcvEv event is signalled,
  248. // when the mask has been set appropriately. If the fAdjustMask flag
  249. // has been set, then the event mask is automatically adjusted.
  250. virtual LONG SetEventChar (BYTE bEventChar, bool fAdjustMask = true);
  251.  
  252. // Set the event mask, which indicates what events should be
  253. // monitored. The WaitEvent method can only monitor events that
  254. // have been enabled. The default setting only monitors the
  255. // error events and data events. An application may choose to
  256. // monitor CTS. DSR, RLSD, etc as well.
  257. virtual LONG SetMask (DWORD dwMask = EEventBreak|EEventError|EEventRecv);
  258.  
  259. // The WaitEvent method waits for one of the events that are
  260. // enabled (see SetMask).
  261. virtual LONG WaitEvent (LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE);
  262.  
  263. // Setup the handshaking protocol. There are three forms of
  264. // handshaking:
  265. //
  266. // 1) No handshaking, so data is always send even if the receiver
  267. // cannot handle the data anymore. This can lead to data loss,
  268. // when the sender is able to transmit data faster then the
  269. // receiver can handle.
  270. // 2) Hardware handshaking, where the RTS/CTS lines are used to
  271. // indicate if data can be sent. This mode requires that both
  272. // ports and the cable support hardware handshaking. Hardware
  273. // handshaking is the most reliable and efficient form of
  274. // handshaking available, but is hardware dependant.
  275. // 3) Software handshaking, where the XON/XOFF characters are used
  276. // to throttle the data. A major drawback of this method is that
  277. // these characters cannot be used for data anymore.
  278. virtual LONG SetupHandshaking (EHandshake eHandshake);
  279.  
  280. // Read operations can be blocking or non-blocking. You can use
  281. // this method to setup wether to use blocking or non-blocking
  282. // reads. Non-blocking reads is the default, which is required
  283. // for most applications.
  284. //
  285. // 1) Blocking reads, which will cause the 'Read' method to block
  286. // until the requested number of bytes have been read. This is
  287. // useful if you know how many data you will receive.
  288. // 2) Non-blocking reads, which will read as many bytes into your
  289. // buffer and returns almost immediately. This is often the
  290. // preferred setting.
  291. virtual LONG SetupReadTimeouts (EReadTimeout eReadTimeout);
  292.  
  293. // Obtain communication settings
  294. virtual EBaudrate GetBaudrate (void);
  295. virtual EDataBits GetDataBits (void);
  296. virtual EParity GetParity (void);
  297. virtual EStopBits GetStopBits (void);
  298. virtual EHandshake GetHandshaking (void);
  299. virtual DWORD GetEventMask (void);
  300. virtual BYTE GetEventChar (void);
  301.  
  302. // Write data to the serial port. Note that we are only able to
  303. // send ANSI strings, because it probably doesn't make sense to
  304. // transmit Unicode strings to an application.
  305. virtual LONG Write (const void* pData, size_t iLen, DWORD* pdwWritten = 0, LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE);
  306. virtual LONG Write (LPCSTR pString, DWORD* pdwWritten = 0, LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE);
  307.  
  308. // Read data from the serial port. Refer to the description of
  309. // the 'SetupReadTimeouts' for an explanation about (non) blocking
  310. // reads and how to use this.
  311. virtual LONG Read (void* pData, size_t iLen, DWORD* pdwRead = 0, LPOVERLAPPED lpOverlapped = 0, DWORD dwTimeout = INFINITE);
  312.  
  313. // Send a break
  314. LONG Break (void);
  315.  
  316. // Determine what caused the event to trigger
  317. EEvent GetEventType (void);
  318.  
  319. // Obtain the error
  320. EError GetError (void);
  321.  
  322. // Obtain the COMM and event handle
  323. HANDLE GetCommHandle (void) { return m_hFile; }
  324.  
  325. // Check if com-port is opened
  326. bool IsOpen (void) const { return (m_hFile != 0); }
  327.  
  328. // Obtain last error status
  329. LONG GetLastError (void) const { return m_lLastError; }
  330.  
  331. // Obtain CTS/DSR/RING/RLSD settings
  332. bool GetCTS (void);
  333. bool GetDSR (void);
  334. bool GetRing (void);
  335. bool GetRLSD (void);
  336.  
  337. // Purge all buffers
  338. LONG Purge (void);
  339.  
  340. protected:
  341. // Internal helper class which wraps DCB structure
  342. class CDCB : public DCB
  343. {
  344. public:
  345. CDCB() { DCBlength = sizeof(DCB); }
  346. };
  347.  
  348. // Attributes
  349. protected:
  350. LONG m_lLastError; // Last serial error
  351. HANDLE m_hFile; // File handle
  352. EEvent m_eEvent; // Event type
  353. DWORD m_dwEventMask; // Event mask
  354.  
  355. #ifndef SERIAL_NO_OVERLAPPED
  356. HANDLE m_hevtOverlapped; // Event handle for internal overlapped operations
  357. #endif
  358.  
  359. protected:
  360. // Check the requirements
  361. void CheckRequirements (LPOVERLAPPED lpOverlapped, DWORD dwTimeout) const;
  362.  
  363. // CancelIo wrapper (for Win95 compatibility)
  364. BOOL CancelCommIo (void);
  365. };
  366.  
  367. #endif // __SERIAL_H
It seems like all of the functions are there in Serial.cpp but unfortunately the Linker Error problem is still there. Any more ideas would be greatly appreciated!

-Sam
Reply With Quote Quick reply to this message  
Join Date: Apr 2006
Posts: 5,051
Reputation: John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold 
Solved Threads: 332
Team Colleague
John A's Avatar
John A John A is offline Offline
Vampirical Lurker

Re: Linker Error

 
0
  #4
Feb 2nd, 2007
You need to make sure that the .cpp files you're trying to compile are actually ADDED to your project, not just in the same directory. Otherwise the compiler has no way of finding them.

If that doesn't work, try cleaning all targets and removing all intermediate files.
"Technological progress is like an axe in the hands of a pathological criminal."

All my posts may be freely redistributed under the terms of the MIT license.
Reply With Quote Quick reply to this message  
Join Date: Feb 2007
Posts: 5
Reputation: Caped Sam is an unknown quantity at this point 
Solved Threads: 0
Caped Sam Caped Sam is offline Offline
Newbie Poster

Re: Linker Error

 
0
  #5
Feb 2nd, 2007
Originally Posted by joeprogrammer View Post
You need to make sure that the .cpp files you're trying to compile are actually ADDED to your project, not just in the same directory. Otherwise the compiler has no way of finding them.
Thanks, Joeprogrammer! That definately cleared up the linker error problem I was having. Do you, in general, need to put ALL relavent .cpp files into a project together before it will work? What about .h files, do they have to be added to the project in the same way? Thanks for all of your help.

Of course, there is a new problem now.

When I compile, I get many errors like this:

130 C:\Dev-Cpp\include\Serial\Serial\Serial.cpp `_CRT_WARN' undeclared (first use this function)

for each time the file Serial.cpp mentions _CRT_WARN, _RPTF0, or _ASSERTE, which amounts to about 57 errors.

Also, in the message window, I am seeing a lot of messages like this:
In destructor
In member function
In member function,
etc.

My compiler dosen't count these messages as errors, so what should I understand them to mean?

Thank you all for your help.

P.S. Since the topic of 'linker error' has been solved for now with this particular program, should I start a new thread when asking about the previously mentioned 'undeclared' errors?

Thanks in advance,
Sam
Reply With Quote Quick reply to this message  
Join Date: Apr 2006
Posts: 5,051
Reputation: John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold John A is a splendid one to behold 
Solved Threads: 332
Team Colleague
John A's Avatar
John A John A is offline Offline
Vampirical Lurker

Re: Linker Error

 
0
  #6
Feb 2nd, 2007
Originally Posted by Caped Sam View Post
Do you, in general, need to put ALL relavent .cpp files into a project together before it will work?
If you're using code from a .cpp file, then yes it has to be included in the project.
Technically header files don't actually have to be included, because header files are actually included with the preprocessor directive #include. Having the header files in the same directory as the rest of your project is all that's required.

When I compile, I get many errors like this:

130 C:\Dev-Cpp\include\Serial\Serial\Serial.cpp `_CRT_WARN' undeclared (first use this function)
It's exactly what the compiler says it is: it has no idea what _CRT_WARN is because it's never been declared. It's probably a flag that you need to #define, so if you haven't written this code, it's a good idea to get documentation for it.

Also, in the message window, I am seeing a lot of messages like this:
In destructor
In member function
In member function,
etc.

My compiler dosen't count these messages as errors, so what should I understand them to mean?
These messages simply help specify where an error is located so you can correct it. Look at previous error messages (or later ones depending on your compiler) to find out the exact cause of the error.
"Technological progress is like an axe in the hands of a pathological criminal."

All my posts may be freely redistributed under the terms of the MIT license.
Reply With Quote Quick reply to this message  
Join Date: Mar 2007
Posts: 45
Reputation: satish.paluvai is an unknown quantity at this point 
Solved Threads: 1
satish.paluvai satish.paluvai is offline Offline
Light Poster

Re: Linker Error

 
0
  #7
Apr 5th, 2007
In my editor that file is not there I dont know wheter it is missed or not.
is it compulasory to use external variables?
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC