Tag Archives: Boost

Download UltraFluid modeler

You can download my application here:

http://www.windowscpp.com/Appz/UltraFluid_Modeler.zip

In the archive there are 2 main folders: bin and images. I have also created a shortcut. Adjust the shortcut to start the app located in bin but place the working directory on the upper folder.

I have a little bug on displaying images by setting the current folder. It will be fixed sooner.

To run the application, you must have vcredist from VS2015. These dll are not distributed in the zip archive.

ultrafluid_modeler_2

Advertisements

Building Boost 1.55 with Visual Studio 2012 and msvc-11

To build Boost last version 1.55, you need Visual Studio 2012 and its native tools command prompt. Just run the bootstrap.bat file and then:

bjam toolset=msvc-11.0 variant=debug,release threading=multi link=shared

It is done.

Upgrading my MFC project and Boost to Visual C++ 2013

First of all, my modeler project hosted at codeplex is compiled with Visual C++ 2012 and vc10 compiler toolset. Why the vc10 compiler ? I use Boost serialization library and sourceforge gives me a static lib called libboost_serialization-vc100-mt-gd-1_51.lib built using vc10. Switching to Visual Studio 2013, I decided to build every thing with Visual C++ 2013, even boost.

First step : building Boost

My project use Boost 1.51 and there are some issue with Boost latest version 1.55 with the serialization library and vc12 (Visual C++ 2013) so I stay with Boost 1.51. There are two commands to launch. The first is bootstrap.bat and the second one is:

> bjam toolset=msvc-12.0 variant=debug,release threading=multi link=shared

The result is in the boost \ stage \ lib folder.

Second step: updating MFC setup

Download the MFC120.dll regular dll from http://www.microsoft.com/en-us/download/details.aspx?id=40770. If your project is built with Unicode character set, it will go OK but if you use not set or multibyte, you can’t compile…

Third step: modify Boost includes to handle a proper link to vc12

Modify the boost_1_51_0\boost\config\auto_link.hpp to handle vc12 (Visual C++ 2013). Add this line 158.

#elif defined(BOOST_MSVC) && (BOOST_MSVC == 1800)
// vc12:
#  define BOOST_LIB_TOOLSET “vc120”

Fourth step: modify my project to use Boost as Dynamic Library for Serialization library

In the stdafx.h, I just add the following defines before including Boost headers:

#define BOOST_SERIALIZATION_DYN_LINK TRUE
#define BOOST_ALL_DYN_LINK TRUE

How to serialize a vector to an XML file using C++ Boost serialization

The Boost library provides a serialization library to serialize objects to XML or text stream. It is very simple to use. Here is my two class, one that contains a vector of shapes and the class of shapes.

//
// CShapeCollection
//
class CShapeCollection
{
public:
	CShapeCollection() {}
	~CShapeCollection() {}

private:
	friend class boost::serialization::access;

	template<class Archive>
	void save(Archive & ar, const unsigned int version) const
	{
		ar & BOOST_SERIALIZATION_NVP(m_shapes);
	}

	template<class Archive>
	void load(Archive & ar, const unsigned int version)
	{
		ar & BOOST_SERIALIZATION_NVP(m_shapes);
	}

    BOOST_SERIALIZATION_SPLIT_MEMBER()

public:
	vector<boost::shared_ptr<CSimpleShape> > m_shapes;
};

BOOST_CLASS_VERSION(CShapeCollection, 1)

//
// CSimpleShape
//
class CSimpleShape
{
public:
	CSimpleShape() {}
	~CSimpleShape() {}

private:
	friend class boost::serialization::access;
	template<class Archive>
	void save(Archive & ar, const unsigned int version) const
	{
		// ar & name;
		// ar & id;
		ar & BOOST_SERIALIZATION_NVP(m_name);
		ar & BOOST_SERIALIZATION_NVP(m_id);
		ar & BOOST_SERIALIZATION_NVP(m_rect);
		ar & BOOST_SERIALIZATION_NVP(m_type);
		ar & BOOST_SERIALIZATION_NVP(m_shapeType);
		ar & BOOST_SERIALIZATION_NVP(m_caption);
		ar & BOOST_SERIALIZATION_NVP(m_text);
		ar & BOOST_SERIALIZATION_NVP(m_x1);
		ar & BOOST_SERIALIZATION_NVP(m_y1);
		ar & BOOST_SERIALIZATION_NVP(m_x2);
		ar & BOOST_SERIALIZATION_NVP(m_y2);
		ar & BOOST_SERIALIZATION_NVP(m_colorFillR);
		ar & BOOST_SERIALIZATION_NVP(m_colorFillG);
		ar & BOOST_SERIALIZATION_NVP(m_colorFillB);
		ar & BOOST_SERIALIZATION_NVP(m_colorLineR);
		ar & BOOST_SERIALIZATION_NVP(m_colorLineG);
		ar & BOOST_SERIALIZATION_NVP(m_colorLineB);
		ar & BOOST_SERIALIZATION_NVP(m_bSolidColorFill);
		ar & BOOST_SERIALIZATION_NVP(m_bColorLine);
		ar & BOOST_SERIALIZATION_NVP(m_bColorFill);
	}

	template<class Archive>
	void load(Archive & ar, const unsigned int version)
	{
		// ar & name;
		// ar & id;
		ar & BOOST_SERIALIZATION_NVP(m_name);
		ar & BOOST_SERIALIZATION_NVP(m_id);
		ar & BOOST_SERIALIZATION_NVP(m_rect);
		ar & BOOST_SERIALIZATION_NVP(m_type);
		ar & BOOST_SERIALIZATION_NVP(m_shapeType);
		ar & BOOST_SERIALIZATION_NVP(m_caption);
		ar & BOOST_SERIALIZATION_NVP(m_text);
		ar & BOOST_SERIALIZATION_NVP(m_x1);
		ar & BOOST_SERIALIZATION_NVP(m_y1);
		ar & BOOST_SERIALIZATION_NVP(m_x2);
		ar & BOOST_SERIALIZATION_NVP(m_y2);
		ar & BOOST_SERIALIZATION_NVP(m_colorFillR);
		ar & BOOST_SERIALIZATION_NVP(m_colorFillG);
		ar & BOOST_SERIALIZATION_NVP(m_colorFillB);
		ar & BOOST_SERIALIZATION_NVP(m_colorLineR);
		ar & BOOST_SERIALIZATION_NVP(m_colorLineG);
		ar & BOOST_SERIALIZATION_NVP(m_colorLineB);
		ar & BOOST_SERIALIZATION_NVP(m_bSolidColorFill);
		ar & BOOST_SERIALIZATION_NVP(m_bColorLine);
		ar & BOOST_SERIALIZATION_NVP(m_bColorFill);
	}
    BOOST_SERIALIZATION_SPLIT_MEMBER()

public:
	string m_name;
	string m_id;
	string m_rect;
	long m_type;
	long m_shapeType;
	string m_caption;
	string m_text;
	long m_x1;
	long m_y1;
	long m_x2;
	long m_y2;
	int m_colorFillR;
	int m_colorFillG;
	int m_colorFillB;
	int m_colorLineR;
	int m_colorLineG;
	int m_colorLineB;
	bool m_bSolidColorFill;
	bool m_bColorLine;
	bool m_bColorFill;
};

BOOST_CLASS_VERSION(CSimpleShape, 1)

Now you have the data, you need to fill it and call the serialize to XML method… In my code, the real data of the application is the CElement. I have a vector of CElement but I need to transfer each element from CElement to SimpleShape witch is the XML container. It is a matter of separation. Then I call boost::archive::xml_oarchive… It is simple.

void CElementManager::Serialize_SaveAsXML(CModeler1View * pView)
{
	CFileDialog dlg(FALSE);
	if( dlg.DoModal() == IDCANCEL )
		return;

	CString strFileName = dlg.GetFileName();
	CString strPath = dlg.GetFolderPath();
	CString strFile;
	strFile.Format("%s\\%s", strPath, strFileName);
	std::string filename = (LPCTSTR)strFile;

	boost::shared_ptr<CShapeCollection> data(new CShapeCollection());

	for( vector<std::shared_ptr<CElement>>::iterator i = m_objects.m_objects.begin() ; i!=m_objects.m_objects.end() ; i++ )
	{
		std::shared_ptr<CElement> pElement = *i;
		boost::shared_ptr<CSimpleShape> pNewElement(new CSimpleShape());
		pNewElement->m_name = pElement->m_name;
		pNewElement->m_id = pElement->m_objectId;
		pNewElement->m_type = pElement->m_type;
		pNewElement->m_shapeType = pElement->m_shapeType;
		pNewElement->m_caption = pElement->m_caption;
		pNewElement->m_text = pElement->m_text;

		CPoint p1 = pElement->m_rect.TopLeft();
		CPoint p2 = pElement->m_rect.BottomRight();
		pNewElement->m_x1 = p1.x;
		pNewElement->m_y1 = p1.y;
		pNewElement->m_x2 = p2.x;
		pNewElement->m_y2 = p2.y;

		pNewElement->m_colorFillR = GetRValue(pElement->m_colorFill);
		pNewElement->m_colorFillG = GetGValue(pElement->m_colorFill);
		pNewElement->m_colorFillB = GetBValue(pElement->m_colorFill);
		pNewElement->m_colorLineR = GetRValue(pElement->m_colorLine);
		pNewElement->m_colorLineG = GetGValue(pElement->m_colorLine);
		pNewElement->m_colorLineB = GetBValue(pElement->m_colorLine);

		pNewElement->m_bSolidColorFill = pElement->m_bSolidColorFill;
		pNewElement->m_bColorLine = pElement->m_bColorLine;
		pNewElement->m_bColorFill = pElement->m_bColorFill;

		data->m_shapes.push_back(pNewElement);
	}

	// load an archive
	std::ofstream xofs(filename.c_str());
	boost::archive::xml_oarchive xoa(xofs);
	xoa << BOOST_SERIALIZATION_NVP(data);

}

Using Boost for XML serialization

In UltraFluid, I add a feature that enable users to save and load diagrams as XML files. The jobs is done using boost 1.51 and its inner library called boost::serialization. It took me some time to adopt the library but is ok now. I made a clone of my objects with only C++ types because boost cannot handle my MFC types like CRect of CPoint. My XML document is a simple: vector<boost::shared_ptr<CSimpleShape> > m_shapes;

I have just transferred my own data type to the boost data type. To avoid namespace collision, I have put std:: prefix on every shared_ptr of my program. The problem is now that I handled two versions of STL in my applications. I should find a solution to use only boost STL.