Visual studio 2012 使用Boost'编译错误;绑定&x27;和Visual Studio 2012 我通过VisualStudioC++访问Boo.Asio调用 串行端口,并将数据传送到C#WPF应用程序。在这篇文章的最后是我用来构建DLL包装器的代码

Visual studio 2012 使用Boost'编译错误;绑定&x27;和Visual Studio 2012 我通过VisualStudioC++访问Boo.Asio调用 串行端口,并将数据传送到C#WPF应用程序。在这篇文章的最后是我用来构建DLL包装器的代码,visual-studio-2012,boost,c++-cli,bind,boost-asio,Visual Studio 2012,Boost,C++ Cli,Bind,Boost Asio,我用VS针对x64编译了Boost库[1.57.0],我 使用Windows7 .\b2链接=共享线程=多地址模型=64级 阻塞读取的代码是有效的,所以我尝试用 超时/异步读取能力 对于方向,我使用了以下帖子: 这些错误源于调用async_read并将绑定结果作为一个结果 参数的选择。最初,错误始于: 错误:“SerialPortInterface::set_result”:缺少函数调用 参数表;使用“&SerialPortInterface::set_result”创建 指向成员的指针 因此

我用VS针对x64编译了Boost库[1.57.0],我 使用Windows7

.\b2链接=共享线程=多地址模型=64级

阻塞读取的代码是有效的,所以我尝试用 超时/异步读取能力

对于方向,我使用了以下帖子:

这些错误源于调用async_read并将绑定结果作为一个结果 参数的选择。最初,错误始于:

错误:“SerialPortInterface::set_result”:缺少函数调用 参数表;使用“&SerialPortInterface::set_result”创建 指向成员的指针

因此,我做出了上述错误消息建议的更改,现在 第一个错误是:

错误:“F”:后跟“:”时必须是类或命名空间

位于boost的“bind.hpp”中。 然后是来自boost源的75条错误消息

这是我的第一个问题。让它编译

我的第二个问题与我对boost和bind的无知有关。 考虑到这一说法:

asio::异步读取(串行端口、oneByteBuffer、, boost::bind(&SerialPortInterface::set_result,&read_result,_1))

有人能告诉我如何调用处理程序“set_result”吗

我读过 并了解此声明的工作原理:

束缚(g,_1,9,_1)(x);//等于g(x,9,x)

因此,使用第一个参数的read_result引用调用处理程序 但是第二个参数使用占位符来填充。。。我迷路了 在这里

Cpp代码:

#include "stdafx.h"

#include "ImprovedAsioDLL.h"

#include <msclr/marshal.h>
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<boost::system::error_code>* a, 
   boost::system::error_code b) 
{ 
    a->reset(b); 
} 

unsigned char SerialPortInterface::readByte()
{
    boost::optional<boost::system::error_code> timer_result;

    deadlineTimer.expires_from_now(boost::posix_time::seconds(1)); 

    // Igor's version
    deadlineTimer.async_wait(boost::bind(&(SerialPortInterface::set_result), 
       &timer_result, _1)); 

    boost::optional<boost::system::error_code>  read_result; 
    // Igor's version
    //boost::asio::async_read(serialPort, oneByteBuffer, 
    //   boost::bind(set_result, &read_result, _1)); 

    // Igor's version with compile error suggestion for 'set_result'
    boost::asio::async_read(serialPort, oneByteBuffer, 
        boost::bind(&SerialPortInterface::set_result, &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->marshal_as<const char*>(portname);
        nativeClassPtr = new SerialPortInterface(str);      
        delete context;
    }
    catch(...)
    {
        throw; // rethrow
    }
}

void AsioInterface::setOptions(int baud)
{
    nativeClassPtr->setOptions(baud);
}

unsigned char AsioInterface::readByte()
{
    // if (nativeClassPtr != nullptr)  ??
    return nativeClassPtr->readByte();
}

// dtor
AsioInterface::~AsioInterface()
{
    this->!AsioInterface();
}

// finalizer
AsioInterface::!AsioInterface()
{
    if (nativeClassPtr != nullptr)
    {
        nativeClassPtr->serialPort.close();
        delete nativeClassPtr;
    }
}
#包括“stdafx.h”
#包括“ImprovedAsioDLL.h”
#包括
使用名称空间msclr::interop;
使用名称空间改进的动态链接库;
/*****Boost.Asio本地类*****************/
SerialPortInterface::SerialPortInterface(常量字符*端口名):io(),
串行端口(io,端口名),死线计时器(io)
{}
void SerialPortInterface::setOptions(整数波特)
{
serialPort.set_选项(boost::asio::serial_port_base::baud_rate(baud));//115200
serialPort.set_选项(boost::asio::serial_port_base::flow_control(boost::asio::serial_port_base::flow_control::none));
serialPort.set_选项(boost::asio::serial_port_base::parity(boost::asio::serial_port_base::parity::none));
serialPort.set_选项(boost::asio::serial_port_base::stop_bits(boost::asio::serial_port_base::stop_bits::one));
serialPort.set_选项(boost::asio::serial_port_base::character_size(8));
}
//伊戈尔版本
void SerialPortInterface::set_result(boost::可选*a,
boost::system::错误(代码b)
{ 
a->重置(b);
} 
无符号字符SerialPortInterface::readByte()
{
boost::可选的定时器结果;
deadlineTimer.expires_from_now(boost::posix_time::seconds(1));
//伊戈尔版本
deadlineTimer.async_wait(boost::bind(&(SerialPortInterface::set_result)),
&计时器_结果,_1));
boost::可选的读取结果;
//伊戈尔版本
//asio::异步读取(串行端口、oneByteBuffer、,
//boost::bind(set_result,&read_result,_1));
//Igor版本,带有“set\u result”的编译错误建议
asio::异步读取(串行端口、oneByteBuffer、,
boost::bind(&SerialPortInterface::set_result,&read_result,_1));
io.reset();
while(io.run_one())
{ 
如果(读取结果)
{
deadlineTimer.cancel();
//从这里返回oneByteBuffer[0]吗?
}
else if(计时器\u结果)
serialPort.cancel();
} 
如果(*读取结果)
抛出boost::system::system\u错误(*读取结果);
返回'c';//TODO-占位符-稍后修复
}
void SerialPortInterface::cancelAsyncOps()
{
serialPort.cancel();
}
/*****C++/CLI托管类*****************/
AsioInterface::AsioInterface(字符串^portname)
{
尝试
{
封送上下文^context=gcnew封送上下文();
const char*str=context->marshal_as(端口名);
nativeClassPtr=新的串行端口接口(str);
删除上下文;
}
捕获(…)
{
抛出;//重新抛出
}
}
void AsioInterface::setOptions(整数波特)
{
nativeClassPtr->setOptions(波特率);
}
无符号字符AsioInterface::readByte()
{
//如果(nativeClassPtr!=nullptr)??
返回nativeClassPtr->readByte();
}
//dtor
AsioInterface::~AsioInterface()
{
此->!AsioInterface();
}
//终结器
AsioInterface::!AsioInterface()
{
如果(nativeClassPtr!=nullptr)
{
nativeClassPtr->serialPort.close();
删除nativeClassPtr;
}
}
及其标题:

#pragma once

using namespace System;
#define BOOST_ALL_DYN_LINK
//#include <boost/cstdint.hpp>  // added to try to fix boost compile errors
#include <boost/asio.hpp> // include boost
#include <boost/asio/deadline_timer.hpp>
#include <boost/optional/optional.hpp>
#include <boost/system/error_code.hpp> 
#include <boost/bind.hpp>


/*****   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<boost::system::error_code>* a, boost::system::error_code b);
    void SerialPortInterface::handle_read ( const boost::system::error_code& 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();
 *
 */
#pragma一次
使用名称空间系统;
#定义BOOST\u ALL\u DYN\u链接
//#添加include//以尝试修复boost编译错误
#include//include boost
#包括
#包括
#包括
#包括
/*****Boost.Asio本地类*****************/
公共结构SerialPortInterface
{
boost::asio::io_服务io;
boost::asio::串行端口serialPort;
boost::asio::deadline\u定时器死线定时器;
无符号字符oneByteBuffer[1];
SerialPortInterface(常量字符*端口名);
无符号字符readByte();
无效实例化端口(常量字符*端口名);
无效设置选项(整数波特);
void cancelAsyncOps();
无效集合结果(boost::optional*a,boost::system::error\u代码b);
void SerialPortInterface::handle\u read(const boost::system::error\u code&ec);
};
/*****C++/CLI托管类*****************/
名称空间改进{
公共参考类AsioInterface
{
SerialPortInterface*nativeClassPtr;
int i;
公众:
AsioInterface(字符串^portname);
无效设置选项(整数波特);
无符号字符readByte();
私人:
~AsioInterface();
!AsioInterface();
};
}
/*
*使用此DLL的C#代码段
*
*字符串portName=“COM22”;
*即时通讯
// ReadTimeOut_CLR_exe.cpp : main project file.

#include "stdafx.h"

// #pragma unmanaged
// push managed state on to stack and set unmanaged state
#pragma managed(push, off)

#include <boost/asio/serial_port.hpp> 
#include <boost/bind.hpp>
#include <boost/asio.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

// #pragma managed
#pragma managed(pop)

using namespace System;
using namespace System::Runtime::InteropServices;

// #pragma unmanaged
// push managed state on to stack and set unmanaged state
#pragma managed(push, off)

class BlockingReader
{

public: 
    BlockingReader(const char *name, size_t timeout);
    bool read_char(char* val);

private:    
    boost::asio::io_service io;
    boost::asio::serial_port port;
    size_t timeout; 
    boost::asio::deadline_timer timer;
    bool read_error;
    char c;

    void time_out(const boost::system::error_code& error);
    void read_complete(const boost::system::error_code& error,
                    size_t bytes_transferred);

};

BlockingReader::BlockingReader(const char *name, size_t timeout) :
    io(), port(io, name), timeout(timeout),
                                timer(io),
                                read_error(true)
{
    port.set_option(boost::asio::serial_port_base::baud_rate(115200));
}

// Reads a character or times out
bool BlockingReader::read_char(char* val) 
{       
    *val = c = '\0';

    // After a timeout & cancel it seems we need
    // to do a reset for subsequent reads to work.
    port.get_io_service().reset();

    // Asynchronously read 1 character.
    boost::asio::async_read(port, boost::asio::buffer(&c, 1), 
            boost::bind(&BlockingReader::read_complete, 
                    this, 
                    boost::asio::placeholders::error, 
                    boost::asio::placeholders::bytes_transferred)); 

    // Setup a deadline time to implement our timeout.
    timer.expires_from_now(boost::posix_time::milliseconds(timeout));
    timer.async_wait(boost::bind(&BlockingReader::time_out,
                            this, boost::asio::placeholders::error));

    // This will block until a character is read
    // or until the it is cancelled.
    port.get_io_service().run();

    if (!read_error)
    {
        *val = c;
    }

    return !read_error;
}

// Called when the timer's deadline expires.
void BlockingReader::time_out(const boost::system::error_code& error) {

    // Was the timeout was cancelled?
    if (error) {
        // yes
        return;
    }

    // no, we have timed out, so kill the read operation
    // The read callback will be called with an error
    port.cancel();
}

// Called when an async read completes or has been cancelled
void BlockingReader::read_complete(const boost::system::error_code& error,
                    size_t bytes_transferred) {     

    read_error = (error || bytes_transferred == 0);

    // Read has finished, so cancel the timer.
    timer.cancel();
}

// #pragma managed
#pragma managed(pop)

public ref struct MyManagedClass {
    BlockingReader *nativeClassPtr;


public:
    MyManagedClass(System::String ^portName, int timeoutMillis)
    {

        // Marshal the managed string to unmanaged memory. 
        char* stringPointer = (char*) Marshal::StringToHGlobalAnsi(portName).ToPointer();

        nativeClassPtr = new BlockingReader(stringPointer, timeoutMillis);

        // Always free the unmanaged string.
        Marshal::FreeHGlobal(IntPtr(stringPointer));
    }

    ~MyManagedClass() { this->!MyManagedClass(); }
    !MyManagedClass() { delete nativeClassPtr; }

    bool readSerialPortByte(System::Byte^ bytePtrHandle)
    {
        pin_ptr<Byte> dontMove = &*bytePtrHandle; 
        unsigned char* ptrByte = dontMove;
        char* ptrByteCast = reinterpret_cast<char*>(ptrByte);
        return this->nativeClassPtr->read_char(ptrByteCast);
    }
};

int main(array<System::String ^> ^args)
{
    Console::WriteLine(L"Testing COM Port 22");
    MyManagedClass myClass("COM22", 500);
    Byte^ oneChar = (Byte)1;

    for (int i=0;i<10;i++)
    {       
        if (myClass.readSerialPortByte(oneChar))
        {
            std::cout << "got byte" << *oneChar << std::endl;
        }
        else
        {
            std::cout << "timed out" << std::endl;
        }
    }
    return 0;
}