title: compile errors with Boost 'bind' and Visual Studio 2012
body: <p>I'm wrapping calls to Boost.Asio via Visual Studio C++ to access a
  serial port and deliver the data to a C# WPF app. At the end of this post is the code I'm using to build the DLL wrapper.</p>
  
  <p>I compiled the Boost libraries [1.57.0] with VS targeting x64 and I'm
  using Windows 7. </p>
  
  <blockquote>
    <p>.\b2 link=shared threading=multi address-model=64 stage</p>
  </blockquote>
  
  <p>The code for the blocking read works, so I tried to improve it with a
  timeout/async read ability.</p>
  
  <p>For direction I used postings from:
    <a href="https://stackoverflow.com/questions/13126776/asioread-with-timeout">asio::read with timeout</a></p>
  
  <p>The errors stem from a call to <em>async_read</em> with <em>bind</em> results as one
  of the parameters. Originally, the errors started with:</p>
  
  <blockquote>
    <p>Error: 'SerialPortInterface::set_result': function call missing
    argument    list; use '&amp;SerialPortInterface::set_result' to create a
    pointer to    member.</p>
  </blockquote>
  
  <p>So I made the change suggested by the above error message and now the 
  first error is:</p>
  
  <blockquote>
    <p>Error: 'F': must be a class or namespace when followed by '::'</p>
  </blockquote>
  
  <p>located in boost's 'bind.hpp'.
  And that is followed by 75 error messages from the boost sources.</p>
  
  <p>That is my first problem. Getting this to compile. </p>
  
  <p>My second problem relates to my ignorance of boost and bind.
  Considering this statement:</p>
  
  <blockquote>
    <p>boost::asio::async_read(serialPort, oneByteBuffer, 
          boost::bind(&amp;SerialPortInterface::set_result, &amp;read_result, _1));</p>
  </blockquote>
  
  <p>Can someone walk me through how the handler 'set_result' is called?</p>
  
  <p>I've read <a href="http://www.boost.org/doc/libs/1_42_0/libs/bind/bind.html#Purpose" rel="nofollow noreferrer">http://www.boost.org/doc/libs/1_42_0/libs/bind/bind.html#Purpose</a>
  and understand how this statement works:</p>
  
  <blockquote>
    <p>bind(g, _1, 9, _1)(x);   // equates to  g(x, 9, x)</p>
  </blockquote>
  
  <p>So the handler is called with the read_result reference for the 1st parameter 
  but the 2nd parameter uses the placeholder to be filled in with... I'm lost 
  here.</p>
  
  <p>Cpp Code:</p>
  
  <pre><code>#include "stdafx.h"
  
  #include "ImprovedAsioDLL.h"
  
  #include &lt;msclr/marshal.h&gt;
  using namespace msclr::interop;
  using namespace ImprovedAsioDLL;
  
  /*****   Boost.Asio Native class *****************/
  
  SerialPortInterface::SerialPortInterface(const char* portName): io(), 
     serialPort(io,portName), deadlineTimer(io)
  {}
  
  void SerialPortInterface::setOptions(int baud)
  {
      serialPort.set_option(boost::asio::serial_port_base::baud_rate(baud)); //115200
      serialPort.set_option(boost::asio::serial_port_base::flow_control( boost::asio::serial_port_base::flow_control::none ));
      serialPort.set_option(boost::asio::serial_port_base::parity ( boost::asio::serial_port_base::parity::none ));
      serialPort.set_option(boost::asio::serial_port_base::stop_bits ( boost::asio::serial_port_base::stop_bits::one ));
      serialPort.set_option(boost::asio::serial_port_base::character_size ( 8 ));
  }
  
  // Igor's version
  void SerialPortInterface::set_result(boost::optional&lt;boost::system::error_code&gt;* a, 
     boost::system::error_code b) 
  { 
      a-&gt;reset(b); 
  } 
  
  unsigned char SerialPortInterface::readByte()
  {
      boost::optional&lt;boost::system::error_code&gt; timer_result;
  
      deadlineTimer.expires_from_now(boost::posix_time::seconds(1)); 
  
      // Igor's version
      deadlineTimer.async_wait(boost::bind(&amp;(SerialPortInterface::set_result), 
         &amp;timer_result, _1)); 
  
      boost::optional&lt;boost::system::error_code&gt;  read_result; 
      // Igor's version
      //boost::asio::async_read(serialPort, oneByteBuffer, 
      //   boost::bind(set_result, &amp;read_result, _1)); 
  
      // Igor's version with compile error suggestion for 'set_result'
      boost::asio::async_read(serialPort, oneByteBuffer, 
          boost::bind(&amp;SerialPortInterface::set_result, &amp;read_result, _1));
  
      io.reset(); 
      while (io.run_one()) 
      { 
        if (read_result) 
        {
          deadlineTimer.cancel(); 
          // return oneByteBuffer[0] from here ? 
        }
        else if (timer_result) 
          serialPort.cancel(); 
      } 
  
      if (*read_result) 
        throw boost::system::system_error(*read_result);
  
  
      return 'c'; // TODO - Placeholder - fix later
  }
  
  void SerialPortInterface::cancelAsyncOps()
  {
      serialPort.cancel();
  }
  
  /*****   C++/CLI managed class *****************/
  
  AsioInterface::AsioInterface(String ^portname)
  {
      try
      {
          marshal_context ^ context = gcnew marshal_context();
          const char* str = context-&gt;marshal_as&lt;const char*&gt;(portname);
          nativeClassPtr = new SerialPortInterface(str);      
          delete context;
      }
      catch(...)
      {
          throw; // rethrow
      }
  }
  
  void AsioInterface::setOptions(int baud)
  {
      nativeClassPtr-&gt;setOptions(baud);
  }
  
  unsigned char AsioInterface::readByte()
  {
      // if (nativeClassPtr != nullptr)  ??
      return nativeClassPtr-&gt;readByte();
  }
  
  // dtor
  AsioInterface::~AsioInterface()
  {
      this-&gt;!AsioInterface();
  }
  
  // finalizer
  AsioInterface::!AsioInterface()
  {
      if (nativeClassPtr != nullptr)
      {
          nativeClassPtr-&gt;serialPort.close();
          delete nativeClassPtr;
      }
  }
  </code></pre>
  
  <p>And its header:</p>
  
  <pre><code>#pragma once
  
  using namespace System;
  #define BOOST_ALL_DYN_LINK
  //#include &lt;boost/cstdint.hpp&gt;  // added to try to fix boost compile errors
  #include &lt;boost/asio.hpp&gt; // include boost
  #include &lt;boost/asio/deadline_timer.hpp&gt;
  #include &lt;boost/optional/optional.hpp&gt;
  #include &lt;boost/system/error_code.hpp&gt; 
  #include &lt;boost/bind.hpp&gt;
  
  
  /*****   Boost.Asio Native class *****************/
  public struct SerialPortInterface
  {
      boost::asio::io_service io;
      boost::asio::serial_port serialPort;
      boost::asio::deadline_timer deadlineTimer;
      unsigned char oneByteBuffer[1];
  
      SerialPortInterface(const char* portName);
  
      unsigned char readByte();
  
      void instantiatePort(const char* portName);
      void setOptions(int baud);
  
      void cancelAsyncOps();
      void set_result(boost::optional&lt;boost::system::error_code&gt;* a, boost::system::error_code b);
      void SerialPortInterface::handle_read ( const boost::system::error_code&amp; ec);
  };
  
  /*****   C++/CLI managed class *****************/
  namespace ImprovedAsioDLL {
  
      public ref class AsioInterface
      {
          SerialPortInterface *nativeClassPtr;
          int i;
  
      public:
          AsioInterface(String ^portname);
  
          void setOptions(int baud);
  
          unsigned char readByte();
      private:
          ~AsioInterface();
          !AsioInterface();
      };
  }
  
  
  /*
   *  C# code snippets using this DLL
   *
   *    string portName = "COM22";
   *    ImprovedAsioDLL.AsioInterface serialPort = new ImprovedAsioDLL.AsioInterface(portName);
   *    this.serialPort.setOptions(115200);
   *    byte chr = this.serialPort.readByte();
   *
   */
  </code></pre>