Back Midas Rome Roody Rootana
  Midas DAQ System  Not logged in ELOG logo
Entry  15 Apr 2019, Konstantin Olchanski, Info, switch of MIDAS to C++ 
    Reply  15 Apr 2019, Konstantin Olchanski, Info, switch of MIDAS to C++, which C++? 
       Reply  15 Apr 2019, Konstantin Olchanski, Info, switch of MIDAS to C++, how much C++? 
          Reply  16 Apr 2019, Pintaudi Giorgio, Info, switch of MIDAS to C++, how much C++? 
          Reply  17 Apr 2019, John M O'Donnell, Info, switch of MIDAS to C++, how much C++? 
             Reply  22 Apr 2019, Pintaudi Giorgio, Info, switch of MIDAS to C++, how much C++? example.cpp
                Reply  23 Apr 2019, Konstantin Olchanski, Info, switch of MIDAS to C++, how much C++? 
       Reply  11 May 2019, Konstantin Olchanski, Info, switch of MIDAS to C++, which C++? 
    Reply  22 May 2019, Konstantin Olchanski, Info, switch of MIDAS to C++ 
       Reply  05 Jun 2019, Konstantin Olchanski, Info, MIDAS switched to C++ 
          Reply  17 May 2022, Razvan Stefan Gornea, Info, MIDAS switched to C++ 
             Reply  17 May 2022, Konstantin Olchanski, Info, MIDAS switched to C++ 
                Reply  17 May 2022, Ben Smith, Info, MIDAS switched to C++ 
Message ID: 1524     Entry time: 22 Apr 2019     In reply to: 1523     Reply to this: 1525
Author: Pintaudi Giorgio 
Topic: Info 
Subject: switch of MIDAS to C++, how much C++? 
Dear Konstantin and others,
our recent discussion stimulated my curiosity and I wrote a small frontend for the trigger board of our experiment in C++.
The underlying hardware details are not relevant here. I would just like to briefly report and discuss what I found out.

I have written all the frontend files (but the bus driver) in C++11:
  • my_frontend.cpp
  • driver/class/my_class_driver.cpp
  • driver/device/my_device_driver.cpp

All went quite smoothly, but I feel that the overall structure is still very C-like (that may be a good thing or a bad thing depending on the point of view).
As far as I know, the MIDAS frontend mfe.c has still only the C version (I couldn't find any mfe.cxx). This means that all the points of contact between the MIDAS frontend code and the user
frontend code must be C compatible (no C++ features or name mangling). To accomplish this I needed to slightly modify the midas.h header file like this:
@@ -1141,7 +1141,13 @@ typedef struct eqpmnt {
+#ifdef __cplusplus
+extern "C" {
+#endif
 INT device_driver(DEVICE_DRIVER *device_driver, INT cmd, ...);
+#ifdef __cplusplus
+}
+#endif

I also tested the new strcomb1 function and it seems to work OK.

I have attached a source file to show how I implemented the device driver in C++. The code is not meant to be compilable: it is just to show how I implemented it. This is the most C++-like syntax that I could come out with. Feel free to comment it and if you think that it could be improved let me know.

Best Regards
Giorgio
Attachment 1: example.cpp  1 kB  Uploaded 22 Apr 2019  | Hide | Hide all
class myDevice {

private:
  // Here goes what in C was the MY_DEVICE_INFO struct
  MY_DEVICE_SETTINGS m_settings;    /* Settings struct of the device */
  void *m_bd_info;                  /* private info of bus driver    */
  HNDLE m_hkey;                     /* ODB key for bus driver info   */
  INT m_channels;                   /* number of channels            */

public:
  myDevice( HNDLE hkey, INT channels, INT(*bd) (INT cmd, ...) )
  {

	// Here goes what in C was my_device_init

  }

  INT myCommand(INT channel, ... /* other arguments */ )
  {

	// Implementation of my_command
  
  }

  ~myDevice()
  {

	// Here goes what in C was my_device_exit
	
  }
};

/*---- device driver entry point -----------------------------------*/

INT my_device(INT cmd, ...)
{
  va_list argptr;
  HNDLE hKey;
  INT channels, channel, status;
  float *pvalue;
  myDevice *pMyDevice;
  INT (*bd) (INT, ...);

  va_start(argptr, cmd);
  status = FE_SUCCESS;

  switch (cmd) {
  case CMD_INIT:
	hKey = va_arg(argptr, HNDLE);
	pMyDevice = va_arg(argptr, myDevice *);
	channels = va_arg(argptr, INT);
	va_arg(argptr, DWORD); // flags
	bd = va_arg(argptr, INT (*) (INT, ...));
	try { pMyDevice = new myDevice(hKey, channels, bd); }
	catch (const std::exception& e) {
	  cm_msg(MERROR, __func__, " init: %s", e.what());
	  status = FE_ERR_DRIVER;
	};
	break;

  case CMD_MY_COMMAND:
	pMyDevice = va_arg(argptr, myDevice *);
	channel = va_arg(argptr, INT);
	// other arguments
	try { status = pMyDevice->myCommand(channel, /* other arguments */); }
	catch (const std::exception& e) {
	  cm_msg(MERROR, __func__, " my command: %s", e.what());
	  if (status == FE_SUCCESS) status = FE_ERR_DRIVER;
	}
	break;

  case CMD_EXIT:
	pMyDevice = va_arg(argptr, myDevice *);
	pMyDevice->~myDevice();
	break;

  default:
	break;
  }

  va_end(argptr);

  return status;
}
ELOG V3.1.4-2e1708b5