14 April 2019

C++ Use Boost property_tree to manipulate xml files


#include "pch.h"
#include <iostream>
#include <string>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>

using namespace std;
int main()
{
 string path = "C:\\Work\\Students.xml";
 string path2 = "C:\\Work\\Students2.xml";
 try
 {
  std::cout << "Using property tree to manipulate XML files\n";
  //how to load an xml file
  boost::property_tree::ptree pt;
  read_xml(path, pt);

  boost::property_tree::ptree& Students = pt.get_child("Students");

  //how to remove a node using Id
  for (auto it = Students.begin(); it != Students.end();)
  {
   int id = it->second.get(".Id");
   if (id == 1)
   {
    it = Students.erase(it);
    
   }
   else
   {
    ++it;
   }
  }
  //how to add nodes
  for (auto data : { 3, 4, 5 })
  {
   boost::property_tree::ptree& Student = Students.add("Student", "");
   Student.add(".Id", data);
   Student.add("LastName", "McDonalds");
   Student.add("FirstName", "Robert");
  }

  //how to save
  write_xml(path2, pt, std::locale(), boost::property_tree::xml_writer_make_settings('\t', 1));

 }
 catch (exception e)
 {
  string s = e.what();
  std::cout << s;
 }
}

08 April 2019

SWIG, pass C++ array of classes back to C# example

Step 1 Create a C++ Windows DLL Project StudentDll


















Step 2 Add Student.h file

#pragma once
#include
#include
class Student
{
public:
std::string FirstName;
std::string LastName;
Student(std::string _FirstName, std::string _LastName);
Student();
};

std::vector GetStudents();

Step 3 Add Student.cpp file

#include "stdafx.h"
#include "Student.h"

Student::Student(std::string _FirstName, std::string _LastName)
{
FirstName = _FirstName;
LastName = _LastName;
}
Student::Student()
{

}

std::vector GetStudents()
{
std::vector sv;
sv.push_back(Student("John", "Smith"));
sv.push_back(Student("Mary", "Boyle"));
return sv;
}

Step 4 Add Student.i file

%module StudentDll
%include "std_string.i"

%apply const std::string& {std::string* FirstName};
%apply const std::string& {std::string* LastName};
%{
#include "student.h"
%}

%include

%include "student.h"

Step 4a


  • Select Student.i, Properties, General, Item Type as Custom Build Tool.
  • Select Apply to create the Custom Build Tool property group.
  • In Custom Build Tool, General, Command Line enter:
    swig -csharp -c++ -outdir  Student.i
  • In Outputs, enter Student_wrap.cxx, and click OK to close the dialog.
  • Right-click Student.i and Compile. This should create four files: three in the C# Generated folder and one in the C++ project.
  • Create a Generated Files filter in the C++ project and add Student_wrap.cxx to it.

  • Step 5 Add StudentVector.i file

    %module StudentVectorDll

    %include std_vector.i
    %include std_string.i

    /* allow partial c# classes */
    %typemap(csclassmodifiers) SWIGTYPE "public partial class"

    /* generate template around vector */

    %template(StudentVector) std::vector;


    Step 5a


  • Select Student.i, Properties, General, Item Type as Custom Build Tool.
  • Select Apply to create the Custom Build Tool property group.
  • In Custom Build Tool, General, Command Line enter:
    swig -csharp -c++ -outdir GeneratedFolderPath StudentVector.i
  • In Outputs, enter StudentVector_wrap.cxx, and click OK to close the dialog.
  • Right-click StudentVector.i and Compile. This should create four files: three in the C# Generated folder and one in the C++ project.
  • Create a Generated Files filter in the C++ project and add StudentVector_wrap.cxx to it.


  • Step 6 Create a C# .Net Framework project StudentConsumer

















    Fill in the default Program.cs file as follow

    using System.Text;
    using System.Threading.Tasks;

    namespace StudentConsumer
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Hello World");
                var s = StudentDllPINVOKE.GetStudents();
                StudentVector sv = new StudentVector(s, true);
                var sv0 = sv[0];
                var sv00 = SWIGTYPE_p_Student.getCPtr(sv0);
                var sv01 = new Student(sv00);
                Console.WriteLine(sv01.FirstName + ", " + sv01.LastName);

                Console.ReadKey();
            }
        }

    }

    Step 7 Add Generated folder in the C# Student Consumer project
    Step 7a Add the content of GeneratedFolderPath folder from C++ StudentDll project to the Generated folder
    Step 7b Add an extra Constructor in the Student.cs

    public class Student : global::System.IDisposable {
      private global::System.Runtime.InteropServices.HandleRef swigCPtr;
      protected bool swigCMemOwn;

      public Student(global::System.Runtime.InteropServices.HandleRef _swigCPtr)
        {
            swigCPtr = _swigCPtr;
        }



















    Step 8 Set the StartUp project as StudentConsumer and Run it










    swig is a good tool for converting interpolating code between C++ and other languages
    http://www.swig.org/