boost multi_index_container serialization - serialization

I am trying to use the boost::multi_index_container with the boost::serialization. However when I use Pointer to objects as elements and a non_unique order, I get a memory access violation loading the serialized container. I find it interesting that the error doesn't occur for unique ordering or using objects instead of pointers as container elements.
Can somebody tell me if there is a problem with my code or if this is a bug in the boost library?
Here is a minimal example that produces the described error:
#include <boost/multi_index_container.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/set.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/member.hpp>
#include <fstream>
using namespace std;
using namespace boost::multi_index;
struct element {
friend class boost::serialization::access;
std::string member1;
element( int num ) { member1 = boost::lexical_cast<string>( num ); }
element() {}
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & member1;
}
};
int main( int argc, const char *argv[] )
{
typedef multi_index_container<element *, indexed_by<ordered_non_unique<member<element, std::string, &element::member1>>>> TestSet;
TestSet myset;
srand( time (NULL ));
for (int i = 0; i < 20; i++) {
myset.insert(new element(rand()));
}
// Write set
ofstream os("test.bin");
boost::archive::binary_oarchive boa(os);
boa << myset;
os.close();
// Read set
TestSet newset;
ifstream is("test.bin");
boost::archive::binary_iarchive bia(is);
bia >> newset;
return 0;
}

ofstream os("test.bin"); should be:
ofstream os("test.bin", ios::binary);
Also:
ifstream is("test.bin"); should be: ifstream is("test.bin", ios::binary);

Related

Simple parsing to a tuple fails

Why does this not compile? The marked line gives me: "static assertion failed: The parser expects tuple-like attribute type". I would think that an std::tuple were the essence of "tuple-like"?
#include <string>
#include <tuple>
#include <boost/spirit/home/x3.hpp>
void parseInteger(std::string input) {
namespace x3 = boost::spirit::x3;
auto iter = input.begin();
auto end_iter = input.end();
int result;
x3::parse(iter, end_iter, x3::int_, result);
}
void parseIntegerAndDouble(std::string input) {
namespace x3 = boost::spirit::x3;
auto iter = input.begin();
auto end_iter = input.end();
std::tuple<int, double> result;
x3::parse(iter, end_iter, x3::int_ >> ' ' >> x3::double_, result); //Compile error!
}
int main(int, char **)
{
parseInteger("567");
parseIntegerAndDouble("321 3.1412");
return 0;
}
The trick is to include two additional header files:
#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/fusion/include/std_tuple.hpp>
This is a bit more magical than I like, but I've got a feeling I really don't want to know how this works!

Integrate boost-asio with file descriptor based socket api from KDB+

I'm relatively new to boost-asio and I'm wondering if it's possible to make it work with KDB+ api here.
I tried something like the below but it doesn't seem to work properly,
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#define KXVER 3
#include "kx/k.h"
using boost::asio::ip::tcp;
namespace posix = boost::asio::posix;
class Feedhandler
{
public:
Feedhandler(boost::asio::io_service &io_service) : m_qsvc(io_service) {
char host[] = "localhost";
int port = 6812;
m_fd = khpu(host, port, "user:pass");
m_qsvc.assign(m_fd);
start_operations();
K ret = k(m_fd, ".u.sub", ks(""), ks(""), (K)0);
}
void start_operations()
{
boost::asio::async_read(m_qsvc, boost::asio::null_buffers(),
boost::bind(&Feedhandler::handle_read, this, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_read(const boost::system::error_code& error, size_t size)
{
K data = k(m_fd,(S)0);
start_operations();
}
private:
int m_fd;
posix::stream_descriptor m_qsvc;
};
int main(int argc, char* argv[])
{
boost::asio::io_service io_service;
Feedhandler fh(io_service);
io_service.run();
return 0;
}
The handle_read method gets hit once and then subsequently there's no more call-backs.
Actually, it's better to use async_wait instead of async_read, like below,
m_qsvc.async_wait(boost::asio::posix::stream_descriptor::wait_read,
boost::bind(&Feedhandler::handle_read, this, boost::asio::placeholders::error) );

read multiple files with quite similar names c++

I am reading a file from current directory
ifstream myfile;
myfile.open("version1.1.hex");
Now a situation is arising that if user updates version then there will be version1.2.hex or version1.3.hex ..so on in the current directory, but one file at a time will be present. I want to write a code now which will cater this future need of reading different file.
I'm writing this code in C++/CLI.
Since file listings are a bit environment-dependant I am not sure if this is helpful to you,
but here is an example how to achieve your goal under the mircosoft regime.
What is needed is the FindFirstFile / FindNextFile calls which query all files matching the fileSearchKey. Then you can use the cFileName part of WIN32_FIND_DATAA as parameter to your open command
string fileSearchKey = "version*";
WIN32_FIND_DATAA fd;
bool bFirstRun = true;
bool bFinishedRun = false;
HANDLE h = INVALID_HANDLE_VALUE;
while (!bFinishedRun)
{
if (bFirstRun)
{
h = FindFirstFileA(fileSearchKey.c_str(), &fd);
bFirstRun = false;
} else
{
if (FindNextFileA(h, &fd) != FALSE)
{
// Abort with error because it has more than one file or decide for the most recent version
} else
{
bFinishedRun = true;
}
}
}
// Load file
ifstream myfile;
myfile.open(fd.cFileName);
This code will look in the directory and take the first file, then quit.
WARNING : this will work only on linux
#include <iostream>
#include <string>
#include <vector>
#include <stdio.h>
#include <cstring>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
using namespace std;
int main ()
{
char n[20];
unsigned char isFolder = 0x4;
unsigned char isFile = 0x8;
DIR *dir;
struct dirent *ent;
dir = opendir ("./");
if (dir != NULL) {
/* print all the files and directories within directory */
while ((ent = readdir (dir)) != NULL) {
//folder sign
if(ent->d_type != isFolder && string(ent->d_name).find("version") != string::npos)
{
cout <<ent->d_name <<"\n";
// Your code
break;
}
}
closedir (dir);
} else {
/* could not open directory */
perror ("");
return 0;
}
cout << "=========" << endl;
}
In C++/CLI you should use the .net framework libraries for this. For instance you can use Directory::GetFiles.
using namespace System;
using namespace System::IO;
int main(array<System::String ^> ^args)
{
array<String^>^dirs = Directory::GetFiles(".", "version1.*.hex");
Collections::IEnumerator^ myEnum = dirs->GetEnumerator();
while (myEnum->MoveNext())
{
Console::WriteLine(myEnum->Current);
}
return 0;
}

simple linux device driver open call crash

I am trying to learn how to write a device driver in linux, following some reference from google and ldd3. i am able to insert the module below but when i tried to open the device in an application the kernel crashed.
The code and build steps followed as below :
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
#include <linux/ioport.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/param.h>
#include <linux/fs.h>
/* =============== Constant Definitions ============ */
#define SERIAL_IRQ 4
/* =============== Variable Definitions ============ */
static int SER_MAJOR = 0;
int ser_open(struct inode *inode, struct file *filp);
int ser_release(struct inode *inode, struct file *filp);
irqreturn_t my_ser_dev_isr(int irq,void *ser_data,struct pt_regs * pt_reg_var)
{
printk("\n\n ------- INTR raised -----------\n\n");
return 0;
}
int ser_open(struct inode *inode, struct file *filp)
{
if(request_irq(SERIAL_IRQ,&my_ser_dev_isr,1,"my_ser_dev_intr",NULL))
{
printk("\n interrupt req failed\n");
}
else
{
enable_irq(SERIAL_IRQ);
printk("\n!!!! ..obtained the requested interrupt and enabled\n");
}
}
int ser_release(struct inode *inode, struct file *filp)
{
disable_irq(SERIAL_IRQ);
free_irq(SERIAL_IRQ,NULL) ;
}
static struct file_operations ser_fops = {
open: ser_open,
release: ser_release
};
void *p = NULL;
irqreturn_t my_ser_dev_isr (int, void *, struct pt_regs *);
static int __init hello_start(void)
{
int ret_val=-1;
int result;
printk(KERN_INFO "Loading hello module...\n");
printk(KERN_INFO "Hello world\n");
result = register_chrdev(SER_MAJOR,"SER_DEV",&ser_fops);
if(result < 0)
{
printk(KERN_WARNING"Can't get major %d\n",SER_MAJOR);
return result;
}
if(SER_MAJOR == 0)
{
SER_MAJOR = result;
printk("SER DEV Major Number : %d",SER_MAJOR );
}
return 0;
}
static void __exit hello_end(void)
{
// free_irq(SERIAL_IRQ,NULL);
//release_region(0x0031,1);
printk(KERN_INFO "Goodbye Mr.\n");
}
module_init(hello_start);
module_exit(hello_end);
Makefile for module :
obj-m := hello.o
default:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
The application used for accesing is as follows :
#include <stdio.h> /* test.c */
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
static int dev;
int main(void)
{
char buff[40];
dev = open("/dev/my_ser_dev",O_RDONLY);
if(dev < 0)
{
printf( "Device Open ERROR!\n");
exit(1);
}
printf("Please push the GPIO_16 port!\n");
//read(dev,buff,40);
// scanf("%s",buff);
printf("%s\n",buff);
close(dev);
return 0;
}
insmod gave
[ 3837.312140] Loading hello module...
[ 3837.312147] Hello world
[ 3837.312218] SER DEV Major Number : 251
Then I created the special file using mknod /dev/my_ser_dev c 251 0
Executing the application caused kernel crash. I am using UBUNTU 3.2.0-23-generic-pae.
The function you are registering as your IRQ handler has the wrong prototype - it should be like
irqreturn_t irq_handler(int, void *);
Maybe you are referring to old documentation.

how to serialize boost::uuids::uuid

I'm currently using boost::uuids::uuid in a project and I want to serialize objects containin boost::uuids::uuid. I tried the simple example below but I get an error:
/usr/include/boost/archive/basic_text_oprimitive.hpp:92: error: no match for ‘operator<<’ in ‘((boost::archive::basic_text_oprimitive >*)this)->boost::archive::basic_text_oprimitive >::os << t’
I would really appriciate if someone could help me.
#include <fstream>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_serialize.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
class classA {
public:
classA() : id(boost::uuids::random_generator()()) {}
private:
friend class boost::serialization::access;
boost::uuids::uuid id;
template <class Archive>
void serialize(Archive& ar, const unsigned int version) {
ar & id;
}
};
int main(void) {
classA a;
std::ofstream ofs("uuid.txt");
boost::archive::text_oarchive oa(ofs);
oa << a;
ofs.close();
return 0;
}
Include <boost/uuid/uuid_serialize.hpp> to enable serialization for uuids.
http://www.boost.org/doc/libs/1_42_0/libs/uuid/uuid.html#boost/uuid/uuid_serialize.hpp