Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > доступ к объектам другого своего приложения


Автор: Incinerated 4.11.2010, 00:14
К примеру есть приложение1, мое собственное. Оно запускается работает и работает скажем к примеру с vector<std::string>... Т.е. хранит какие то строки в процессе своей работы, работа непрерывная. Т.е. конец  у нее есть, но по окончании процесс запускается заново.
Есть приложение2, тоже мое, которому нужно получить в любой момент времени доступ к данному вектору из приложения1. Каким образом этом можно организовать без использования файловой системе(запись в файл/чтение из файла), т.е. можно ли это организовать в памяти все и каким образом?
И еще вопрос, можно ли изменять значения переменных приложения1 из приложения2, например, типа bool и тоже каким образом?

P.S. я даже не знаю как это в гугле искать и не имею представления есть ли такие возможности, поэтому спрашиваю здесь. Спасибо.

Автор: Cheloveck 4.11.2010, 00:31
Цитата(Incinerated @  4.11.2010,  00:14 Найти цитируемый пост)
 есть ли такие возможности

есть

Цитата(Incinerated @  4.11.2010,  00:14 Найти цитируемый пост)
не знаю как это в гугле искать
  • Shared memory
  • Проекция файла в память
  • Пайпы
  • Сокеты

Добавлено через 1 минуту и 1 секунду
Только обращу внимание на то, что программы должны иметь один и тот же рантайм, для корректной работы с STL объектами.

Автор: Incinerated 4.11.2010, 11:28
нашел пример по вот этому: 
Код

CreateFileMapping()
...

но у меня возникла сразу проблема. У меня вектор классов, и внутри этого класса есть другие классы, небольшой пример:
Код

class c1{
private:
  wstring a,b;
publuc:
 c1(){};
 wstring getA() {return a;}
 wstring getb() {return b;}
 void setA(wstring str) {a = str;}
 void setB(wstring str) {b = str;}
};

class c2{
private:
  vector<c1> v1;
  vector<c2> v2;
...
}

class c3{
private:
 vector<c1> v1;
 vector<c2> v2;
...
}

class c4{
private:
  vector<c3> v1;
...
}

вот примерно такая структура приложения1. Каким образом мне это загнать в FileMapping? просто в итоге, кол-во элементов класса c1 может достигнуть и одного миллиона.

Автор: boostcoder 4.11.2010, 11:39
Цитата(Incinerated @  4.11.2010,  11:28 Найти цитируемый пост)
CreateFileMapping()

даже не представляю как это может помочь задаче..
дай ссылку на пример.

я для подобных задач использую http://www.boost.org/doc/libs/1_44_0/doc/html/interprocess.html.
конкретно ваша задача http://www.boost.org/doc/libs/1_44_0/doc/html/interprocess/quick_guide.html#interprocess.quick_guide.qg_interprocess_container.

Автор: Incinerated 4.11.2010, 13:06
Цитата(boostcoder @ 4.11.2010,  10:39)
Цитата(Incinerated @  4.11.2010,  11:28 Найти цитируемый пост)
CreateFileMapping()

даже не представляю как это может помочь задаче..
дай ссылку на пример.

я для подобных задач использую http://www.boost.org/doc/libs/1_44_0/doc/html/interprocess.html.
конкретно ваша задача http://www.boost.org/doc/libs/1_44_0/doc/html/interprocess/quick_guide.html#interprocess.quick_guide.qg_interprocess_container.

http://msdn.microsoft.com/en-us/library/aa366551%28VS.85%29.aspx

а по поводу boost.interprocess есть вопрос, мне каждый вектор нужно так описать?

Автор: boostcoder 4.11.2010, 13:11
Цитата(Incinerated @  4.11.2010,  13:06 Найти цитируемый пост)
мне каждый вектор нужно так описать? 

только тип.

Добавлено через 1 минуту и 33 секунды
Цитата(Incinerated @  4.11.2010,  13:06 Найти цитируемый пост)
http://msdn.microsoft.com/en-us/library/aa...28VS.85%29.aspx

и нафига вам это? это же просто байт-хранилище.

Автор: Incinerated 4.11.2010, 13:15
Цитата(boostcoder @ 4.11.2010,  12:11)
Добавлено @ 13:12
Цитата(Incinerated @  4.11.2010,  13:06 Найти цитируемый пост)
http://msdn.microsoft.com/en-us/library/aa...28VS.85%29.aspx

и нафига вам это? это же просто байт-хранилище.

я просто не знал как организовать такую вещь и мне чуть выше посоветовали нечто похожее, на что я и нашел пример =)

Автор: Incinerated 4.11.2010, 13:36
Цитата(boostcoder @ 4.11.2010,  10:39)
я для подобных задач использую http://www.boost.org/doc/libs/1_44_0/doc/html/interprocess.html.
конкретно ваша задача http://www.boost.org/doc/libs/1_44_0/doc/html/interprocess/quick_guide.html#interprocess.quick_guide.qg_interprocess_container.

Код

//Create a new segment with given name and size
      managed_shared_memory segment(create_only, "MySharedMemory", 65536);
      

вот тут указан размер 65536, я так понимаю сегмент нужно создавать до заполнения векторов и как узнать какой объем памяти выделять к примеру на 100 000 элементов или на 1 миллион? Нельзя же точно знать какой объем они будут занимать. Или можно написать скажем 1 миллиард(1 Gb) и все будет норм? Но опять таки, а если не хватит памяти или не надо столько, как быть с этим?

Автор: boostcoder 4.11.2010, 13:44
Цитата(Incinerated @  4.11.2010,  13:36 Найти цитируемый пост)
Или можно написать скажем 1 миллиард(1 Gb) и все будет норм?

так указывается максимальный размер сегмента. память сразу не выделяется. но наверное это зависит от ОСи. к примеру на линукс, у меня сегмент 8GB. а реально выделяется памяти масими 3.7GB когда в сегменте уже расположены объекты.

Цитата(Incinerated @  4.11.2010,  13:36 Найти цитируемый пост)
Но опять таки, а если не хватит памяти

получите исключение boost::interprocess::bad_alloc

Добавлено через 11 минут и 18 секунд
Цитата(boostcoder @  4.11.2010,  13:44 Найти цитируемый пост)
реально выделяется памяти масими 3.7GB когда в сегменте уже расположены объекты.

т.е. суммарный объем объектов чуть меньше.

Автор: Incinerated 4.11.2010, 18:35
я все-таки не особо понял как мне нужно описать вектора мои, описав главный вот так:
Код

typedef allocator<с3, managed_shared_memory::segment_manager>  ShmemAllocator;

//Alias a vector that uses the previous STL-like allocator so that allocates
//its values from the segment
typedef vector<с3, ShmemAllocator> MyVector;

int main(int argc, _TCHAR* argv[])
{
    
   if(argc == 1){ //Parent process
      //Remove shared memory on construction and destruction
      struct shm_remove 
      {
         shm_remove() { shared_memory_object::remove("MySharedMemory"); }
         ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
      } remover;

      //Create a new segment with given name and size
      managed_shared_memory segment(create_only, "MySharedMemory", 65536);

      //Initialize shared memory STL-compatible allocator
      const ShmemAllocator alloc_inst (segment.get_segment_manager());

      //Construct a vector named "MyVector" in shared memory with argument alloc_inst
      MyVector *myvector = segment.construct<MyVector>("MyVector")(alloc_inst);

      for(int i = 0; i < 10; ++i){  //Insert data in the vector
         с3 tmp(L"A");
                 myvector->push_back(tmp);
      }
       _getch();
        segment.destroy<MyVector>("MyVector");
   }
   else{ //Child process
      //Open the managed segment
      managed_shared_memory segment(open_only, "MySharedMemory");  

      //Find the vector using the c-string name
      MyVector *myvector = segment.find<MyVector>("MyVector").first;
    

      //Use vector in reverse order
      MyVector::iterator it = myvector->begin();
      for (; it <myvector->end(); it++){
          c3 tmp = *it;          
          std::wcout << tmp.GetName() << std::endl;
      }
      //When done, destroy the vector from the segment
      segment.destroy<MyVector>("MyVector");
      _getch();
   }

   return 0;
}


вроде ничего лишнего нету, этот пример рабочий, хоть в нем и вырезаны куски, но я самое основное оставил. Т.е. когда запускаешь без параметра программа заполняет вектор и хранит его в общей памяти с таким-то названием, когда с параметром запускаешь он читает данные из этой памяти и выводит в консоль, все в принципе работает. Но возникает проблема когда я добавляю в класс, к примеру, c3 вектор класса c1. Как его нужно описать? описал как vector<c1> *v1 = new vector<c1>;, данные заносятся в вектор myvector, проверил, а вот считаться они не могут, т.е. когда запускаешь программу с параметром для считывания данных, данные класса с3, например, типа wstring считываются, а вектор v1 - пуст. Просто для меня это все ново и не понятно. Как надо было описать вектор класса с1?

Автор: boostcoder 4.11.2010, 18:53
Цитата(Incinerated @  4.11.2010,  18:35 Найти цитируемый пост)
Но возникает проблема когда я добавляю в класс, к примеру, c3 вектор класса c1. Как его нужно описать? описал как vector<c1> *v1 = new vector<c1>;

покажи код.

Автор: Incinerated 4.11.2010, 19:08
Код

// eeeee.cpp: определяет точку входа для консольного приложения.
//

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <tchar.h> 
#include <strsafe.h>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <string>
#include <cstdlib> //std::system
#include <conio.h>
using namespace boost::interprocess;

class sFile
{
private:
    std::wstring m_place;
        std::wstring m_name;
public:
    std::wstring GetName() { return m_name; }
    sFile(){};
    sFile(std::wstring place, std::wstring name) :
    m_place(place), m_name(name)
    {}
};

class sDrive
{
private:

    std::wstring m_name;

        int m_count_files;
        int m_count_dirs;
public:
    vector<sFile> *m_files;
    std::wstring GetName() { return m_name; }
    sDrive(){};
    sDrive(std::wstring name) :
    m_name(name)
    {
        m_count_files = m_count_dirs = 0; 
      m_files = new vector<sFile>;
    }
};



typedef allocator<sDrive, managed_shared_memory::segment_manager>  ShmemAllocator;

typedef vector<sDrive, ShmemAllocator> MyVector;

int main(int argc, _TCHAR* argv[])
{
    
   if(argc == 1){ //Parent process
      //Remove shared memory on construction and destruction
      struct shm_remove 
      {
         shm_remove() { shared_memory_object::remove("MySharedMemory"); }
         ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
      } remover;

      //Create a new segment with given name and size
      managed_shared_memory segment(create_only, "MySharedMemory", 65536);

      //Initialize shared memory STL-compatible allocator
      const ShmemAllocator alloc_inst (segment.get_segment_manager());

      //Construct a vector named "MyVector" in shared memory with argument alloc_inst
      MyVector *myvector = segment.construct<MyVector>("MyVector")(alloc_inst);

      for(int i = 0; i < 10; ++i){  //Insert data in the vector
         sDrive tmp(L"A");
         sFile tmp2(L"b",L"c");
         tmp.m_files->push_back(tmp2);
         myvector->push_back(tmp);
      }
      _getch();
   }
   else{ //Child process
      //Open the managed segment
      managed_shared_memory segment(open_only, "MySharedMemory");  

      //Find the vector using the c-string name
      MyVector *myvector = segment.find<MyVector>("MyVector").first;
    

      //Use vector in reverse order
//      std::sort(myvector->rbegin(), myvector->rend());
      MyVector::iterator it = myvector->begin();
      for (; it <myvector->end(); it++){
          sDrive tmp = *it;          
          vector<sFile>::iterator it1 = tmp.m_files->begin();
          std::wcout << (*it1).GetName() << std::endl;
      }
      //When done, destroy the vector from the segment
      segment.destroy<MyVector>("MyVector");
      _getch();
   }

   return 0;
}


т.е. на строчке: vector<sFile>::iterator it1 = tmp.m_files->begin(); кидает ошибку памяти... в отладке видно что вектор m_files пуст.

Автор: boostcoder 4.11.2010, 19:38
Цитата(Incinerated @  4.11.2010,  19:08 Найти цитируемый пост)
m_files = new vector<sFile>;

уберите new.
во первых - нелепо использовать new тут.
во вторых - проблема по все видимости в этом.

Добавлено @ 19:40
Цитата(Incinerated @  4.11.2010,  19:08 Найти цитируемый пост)
class sFile
{
private:
    std::wstring m_place;
        std::wstring m_name;
public:
    std::wstring GetName() { return m_name; }
    sFile(){};
    sFile(std::wstring place, std::wstring name) :
    m_place(place), m_name(name)
    {}
};
class sDrive
{
private:
    std::wstring m_name;
        int m_count_files;
        int m_count_dirs;
public:
    vector<sFile> *m_files;
    std::wstring GetName() { return m_name; }
    sDrive(){};
    sDrive(std::wstring name) :
    m_name(name)
    {
        m_count_files = m_count_dirs = 0; 
      m_files = new vector<sFile>;
    }
};

я бы это заменил на:
Код

struct fs_tree {
   тут несколько аксессоров.
private:
   std::map<wstring, std::vector<wstring> > _tree;
};

Автор: Incinerated 4.11.2010, 21:25
Цитата(boostcoder @  4.11.2010,  18:38 Найти цитируемый пост)

уберите new.
во первых - нелепо использовать new тут.
во вторых - проблема по все видимости в этом.

Почему нелепо создавать объект в конструкторе класса? И почему проблема в этом, если в этом куске кода все работает как я и писал выше:
Код

    for(int i = 0; i < 10; ++i){  //Insert data in the vector
         sDrive tmp(L"A");
         sFile tmp2(L"b",L"c");
         tmp.m_files->push_back(tmp2);
         myvector->push_back(tmp);
      }

т.е. если после цикла запустить цикл выводящий элементы вектора m_files, то он все выводит хорошо. А во 2-ом приложении вектор пуст. И каким образом инициализация вектора в конструкторе может этому мешать?

Цитата(boostcoder @  4.11.2010,  18:38 Найти цитируемый пост)

я бы это заменил на:
Код

struct fs_tree {
   тут несколько аксессоров.
private:
   std::map<wstring, std::vector<wstring> > _tree;
};


что такое аксессоры? и у вас получилось map - карта? слышал, но толком не знаю, но так как вы назвали _tree - это видимо некое дерево или граф. И получается каждая ветка имеет 2 значения wstring и вектор типа wstring и все, а мне надо больше у меня sFile имеет более 10 переменных, их все перечислять через запятую или как? и как с этим тогда работать, и почему нельзя сделать так как я написал(структура)?

Автор: boostcoder 4.11.2010, 21:37
Цитата(Incinerated @  4.11.2010,  21:25 Найти цитируемый пост)
Почему нелепо создавать объект в конструкторе класса?

потому что -
Цитата(boostcoder @  4.11.2010,  19:38 Найти цитируемый пост)
нелепо использовать new тут


Цитата(Incinerated @  4.11.2010,  21:25 Найти цитируемый пост)
И почему проблема в этом, если в этом куске кода все работает как я и писал выше:

Цитата(Incinerated @  4.11.2010,  21:25 Найти цитируемый пост)
т.е. если после цикла запустить цикл выводящий элементы вектора m_files, то он все выводит хорошо. А во 2-ом приложении вектор пуст. И каким образом инициализация вектора в конструкторе может этому мешать?

вы пытаетесь расшарить область памяти между процессами. при этом, часть объектов которые должны быть в расшаренной памяти, создаете в локальной памяти процесса. и как в таком случае, сторонний процесс получит локальную память другого процесса? smile 

Цитата(Incinerated @  4.11.2010,  21:25 Найти цитируемый пост)
и у вас получилось map - карта?

типа того. где ключ - имя каталога, а значение - список имен файлов этого каталога. это как пример. храните в векторе не строки, и ваши структуры. разницы никакой..

Автор: Incinerated 4.11.2010, 21:51
Цитата(boostcoder @ 4.11.2010,  20:37)
вы пытаетесь расшарить область памяти между процессами. при этом, часть объектов которые должны быть в расшаренной памяти, создаете в локальной памяти процесса. и как в таком случае, сторонний процесс получит локальную память другого процесса? smile 

Цитата(Incinerated @  4.11.2010,  21:25 Найти цитируемый пост)
и у вас получилось map - карта?

типа того. где ключ - имя каталога, а значение - список имен файлов этого каталога. это как пример. храните в векторе не строки, и ваши структуры. разницы никакой..

Никак =) я и попытался описать вектор <sFile> как описал вектор <sDrive>, но ничего не вышло. Получается под каждый вектор m_files нужно назначать новое имя расшаренной области памяти или как?
И если использовать map, то думаю возникнет еще больше вопросов  smile 

Автор: boostcoder 4.11.2010, 21:52
Цитата(Incinerated @  4.11.2010,  21:51 Найти цитируемый пост)
я и попытался описать вектор <sFile> как описал вектор <sDrive>, но ничего не вышло. Получается под каждый вектор m_files нужно назначать новое имя расшаренной области памяти или как?

уберите new!

Добавлено через 4 минуты и 19 секунд
не утверждаю что проблема в этом.
если не поможет - будем думать дальше.

Автор: Incinerated 5.11.2010, 10:01
Цитата(boostcoder @ 4.11.2010,  20:52)

уберите new!

Добавлено @ 21:56
не утверждаю что проблема в этом.
если не поможет - будем думать дальше.

убрал new...
теперь вывод на экран вот такой:
Код

      MyVector::iterator it = myvector->begin();
      for (; it <myvector->end(); it++){      
          vector<sFile>::iterator it1 = (*it).m_files.begin();
          std::wcout << (*it1).GetName() << std::endl;
      }

если в отладке посмотреть что находится в it, то переменные wstring имеются и даже имеется какой то вектор m_files, т.е. у него пишется размер "1", т.е. там что то есть, но данные m_place и m_name ссылаются на не известные области памяти =\ получается что к ним нету доступа. Но интересно вот что, если заменить выше код на такой, то ошибку памяти не кидает, а выводит на экран пустые строки :(
Код

      MyVector::iterator it = myvector->begin();
      for (; it <myvector->end(); it++){
          sDrive &tmp = *it;          
          vector<sFile>::iterator it1 = tmp.m_files.begin();
          std::wcout << (*it1).GetName() << std::endl;
      }

Автор: boostcoder 5.11.2010, 13:27
опишите вложенный вектор так, как основной.
и выложите компилябельный пример.

Автор: Incinerated 5.11.2010, 13:30
Цитата(boostcoder @ 5.11.2010,  12:27)
опишите вложенный вектор так, как основной.
и выложите компилябельный пример.

А название области памяти ему какое писать? 
или просто описать вот так?
Код

typedef allocator<sFile, managed_shared_memory::segment_manager>  ShmemAllocator1;
typedef vector<sFile, ShmemAllocator1> MyVector1;


Автор: Incinerated 5.11.2010, 13:50
вот компиляберный код, и даже рабочий, т.е. выводится все хорошо теперь, но вопрос у меня возник, я организовал создание вектора m_files в общей памяти и каждому новому вектору приходится давать новое имя: MyVector0,MyVector1,MyVector2 и т.д., это нормально или можно обойтись без этого как то?
Код

// eeeee.cpp: определяет точку входа для консольного приложения.
//

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <tchar.h> 
#include <strsafe.h>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <string>
#include <cstdlib> //std::system
#include <conio.h>
using namespace boost::interprocess;

class sFile
{
private:
    std::wstring m_place;
        std::wstring m_name;
public:
    std::wstring GetName() { return m_name; }
    sFile(){};
    sFile(std::wstring place, std::wstring name) :
    m_place(place), m_name(name)
    {}
};

typedef allocator<sFile, managed_shared_memory::segment_manager>  ShmemAllocator1;

typedef vector<sFile, ShmemAllocator1> MyVector1;

class sDrive
{
private:

    std::wstring m_name;

        int m_count_files;
        int m_count_dirs;
public:
    MyVector1 *m_files;
    std::wstring GetName() { return m_name; }
    sDrive(){};
    sDrive(std::wstring name) :
    m_name(name)
    {
        m_count_files = m_count_dirs = 0; 
      //m_files = new vector<sFile>;
    }
};



typedef allocator<sDrive, managed_shared_memory::segment_manager>  ShmemAllocator;

typedef vector<sDrive, ShmemAllocator> MyVector;

int main(int argc, _TCHAR* argv[])
{
    
   if(argc == 1){ //Parent process
      //Remove shared memory on construction and destruction
      struct shm_remove 
      {
         shm_remove() { shared_memory_object::remove("MySharedMemory"); }
         ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
      } remover;

      //Create a new segment with given name and size
      managed_shared_memory segment(create_only, "MySharedMemory", 65536);

      //Initialize shared memory STL-compatible allocator
      const ShmemAllocator alloc_inst (segment.get_segment_manager());

      //Construct a vector named "MyVector" in shared memory with argument alloc_inst
      MyVector *myvector = segment.construct<MyVector>("MyVector")(alloc_inst);

      for(int i = 0; i < 10; ++i){  //Insert data in the vector
         sDrive tmp(L"A");
         sFile tmp2(L"b",L"c");
         std::string str = "MyVector";
         char buf[5];
         itoa(i,buf,10);
         str = str + buf;
         tmp.m_files = segment.construct<MyVector1>(str.c_str())(alloc_inst);
         tmp.m_files->push_back(tmp2);
         myvector->push_back(tmp);
      }
      _getch();
   }
   else{ //Child process
      //Open the managed segment
      managed_shared_memory segment(open_only, "MySharedMemory");  

      //Find the vector using the c-string name
      MyVector *myvector = segment.find<MyVector>("MyVector").first;
    

      //Use vector in reverse order
//      std::sort(myvector->rbegin(), myvector->rend());
      MyVector::iterator it = myvector->begin();
      for (; it <myvector->end(); it++){
          sDrive &tmp = *it;          
          MyVector1::iterator it1 = tmp.m_files->begin();
          std::wcout << (*it1).GetName() << std::endl;
      }
      //When done, destroy the vector from the segment
      segment.destroy<MyVector>("MyVector");
      _getch();
   }

   return 0;
}

Автор: boostcoder 5.11.2010, 14:00
Цитата(Incinerated @  5.11.2010,  13:50 Найти цитируемый пост)
это нормально или можно обойтись без этого как то?

честно говоря...не знаю. погуглите. помоему должен быть какой-то более адекватный способ.

Автор: Incinerated 9.11.2010, 10:41
столкнулся с проблемой: ругается на сериализацию вектора. В этой теме http://forum.vingrad.ru/topic-313168.html мы вроде как разобрались как это сделать, но добавив общую память компилятор стал сильно ругаться на сериализацию/десериализацию, мол:
Код

C:\Program Files\Microsoft Visual Studio 9.0\VC\include\boost/serialization/access.hpp(118) : error C2039: serialize: не является членом "boost::container::vector<T,A>"
1>        with
1>        [
1>            T=sDrive,
1>            A=ShmemAllocatorDrives
1>        ]
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\boost/serialization/serialization.hpp(70): см. ссылку на создание экземпляров функции шаблон при компиляции 
"void boost::serialization::access::serialize<Archive,T>(Archive &,T &,const unsigned int)"
1>        with
1>        [
1>            Archive=boost::archive::binary_oarchive,
1>            T=VectorDrives
1>        ]
1>        C:\Program Files\Microsoft Visual Studio 9.0\VC\include\boost/serialization/serialization.hpp(129): см. ссылку на создание экземпляров функции шаблон при компиляции 
"void boost::serialization::serialize<Archive,T>(Archive &,T &,const unsigned int)"
1>        with
1>        [
1>            Archive=boost::archive::binary_oarchive,
1>            T=VectorDrives
1>        ]

и там еще много чего написано, если закомментировать сериализацию/десериализацию то все норм... Вот описание одного из векторов:
Код

typedef boost::interprocess::allocator<sDrive, managed_shared_memory::segment_manager>  ShmemAllocatorDrives;

typedef boost::container::vector<sDrive, ShmemAllocatorDrives> VectorDrives;

Как можно решить эту проблему, чтобы и в файл писалось и чтобы было в общей памяти?

Автор: boostcoder 9.11.2010, 13:04
<boost/serialization/vector.hpp> подключен?

Автор: Incinerated 9.11.2010, 15:57
Цитата(boostcoder @ 9.11.2010,  12:04)
<boost/serialization/vector.hpp> подключен?

да

Автор: boostcoder 9.11.2010, 17:20
Цитата(Incinerated @  9.11.2010,  10:41 Найти цитируемый пост)
T=sDrive


Цитата(Incinerated @  9.11.2010,  10:41 Найти цитируемый пост)
T=VectorDrives

для этих типов сериализация реализована?

Добавлено через 55 секунд
несколькими постами выше, она не реализована.

Автор: Incinerated 9.11.2010, 20:49
кусок класса sDrive:
Код

class sDrive
{
public:
    typedef boost::interprocess::allocator<sDrive, managed_shared_memory::segment_manager>  ShmemAllocatorDrives;

    typedef boost::container::vector<sDrive, ShmemAllocatorDrives> VectorDrives;
private:
    friend class boost::serialization::access;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & BOOST_SERIALIZATION_NVP(m_name);
        ar & BOOST_SERIALIZATION_NVP(m_files);
        ar & BOOST_SERIALIZATION_NVP(m_dirs);
        ar & BOOST_SERIALIZATION_NVP(m_count_files);
        ar & BOOST_SERIALIZATION_NVP(m_count_dirs);
    }
    VectorFiles *m_files;
    sDir::VectorDirs *m_dirs;
    wstring m_name;
    int m_count_files;
    int m_count_dirs;

далее, объявление вектора класса sDrive:
Код

    sDrive::VectorDrives *drives;

вот, и не знаю в чем ошибка  smile 
ну еще приведу запись и чтение функции:
Код

template<typename TOArch, typename TClass>
void MySearch::writeFile(const std::string & file, const TClass & cont)
{
 
    { // Сериализуем
        std::ofstream ofs(file.c_str(), std::ios::out|std::ios::trunc|std::ios::binary);
        TOArch oa(ofs);
        oa << boost::serialization::make_nvp("Test_Object", cont); 
    }
}

template<typename TIArch, typename TClass>
TClass& MySearch::readFile(const std::string& file, TClass& cont)
{
    { // Десериализуем
        std::ifstream ifs(file.c_str(), std::ios::in|std::ios::binary);
        TIArch ia(ifs);
        ia >> boost::serialization::make_nvp("Test_Object",cont);
    }
    return cont;
}

int MySearch::Save()
{
//    writeFile<boost::archive::binary_oarchive>(filename, drives);
    return 0;
}

int MySearch::Load()
{        
//    readFile<boost::archive::binary_iarchive>(filename, drives);
    return 0;
}

там вызов запись и чтения заккоментен, ибо если раскомментить лезут ошибки, что описал выше...

Автор: Incinerated 12.11.2010, 14:28
Цитата(Incinerated @ 5.11.2010,  12:50)
вот компиляберный код, и даже рабочий, т.е. выводится все хорошо теперь, но вопрос у меня возник, я организовал создание вектора m_files в общей памяти и каждому новому вектору приходится давать новое имя: MyVector0,MyVector1,MyVector2 и т.д., это нормально или можно обойтись без этого как то?
Код

// eeeee.cpp: определяет точку входа для консольного приложения.
//

#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <tchar.h> 
#include <strsafe.h>
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <string>
#include <cstdlib> //std::system
#include <conio.h>
using namespace boost::interprocess;

class sFile
{
private:
    std::wstring m_place;
        std::wstring m_name;
public:
    std::wstring GetName() { return m_name; }
    sFile(){};
    sFile(std::wstring place, std::wstring name) :
    m_place(place), m_name(name)
    {}
};

typedef allocator<sFile, managed_shared_memory::segment_manager>  ShmemAllocator1;

typedef vector<sFile, ShmemAllocator1> MyVector1;

class sDrive
{
private:

    std::wstring m_name;

        int m_count_files;
        int m_count_dirs;
public:
    MyVector1 *m_files;
    std::wstring GetName() { return m_name; }
    sDrive(){};
    sDrive(std::wstring name) :
    m_name(name)
    {
        m_count_files = m_count_dirs = 0; 
      //m_files = new vector<sFile>;
    }
};



typedef allocator<sDrive, managed_shared_memory::segment_manager>  ShmemAllocator;

typedef vector<sDrive, ShmemAllocator> MyVector;

int main(int argc, _TCHAR* argv[])
{
    
   if(argc == 1){ //Parent process
      //Remove shared memory on construction and destruction
      struct shm_remove 
      {
         shm_remove() { shared_memory_object::remove("MySharedMemory"); }
         ~shm_remove(){ shared_memory_object::remove("MySharedMemory"); }
      } remover;

      //Create a new segment with given name and size
      managed_shared_memory segment(create_only, "MySharedMemory", 65536);

      //Initialize shared memory STL-compatible allocator
      const ShmemAllocator alloc_inst (segment.get_segment_manager());

      //Construct a vector named "MyVector" in shared memory with argument alloc_inst
      MyVector *myvector = segment.construct<MyVector>("MyVector")(alloc_inst);

      for(int i = 0; i < 10; ++i){  //Insert data in the vector
         sDrive tmp(L"A");
         sFile tmp2(L"b",L"c");
         std::string str = "MyVector";
         char buf[5];
         itoa(i,buf,10);
         str = str + buf;
         tmp.m_files = segment.construct<MyVector1>(str.c_str())(alloc_inst);
         tmp.m_files->push_back(tmp2);
         myvector->push_back(tmp);
      }
      _getch();
   }
   else{ //Child process
      //Open the managed segment
      managed_shared_memory segment(open_only, "MySharedMemory");  

      //Find the vector using the c-string name
      MyVector *myvector = segment.find<MyVector>("MyVector").first;
    

      //Use vector in reverse order
//      std::sort(myvector->rbegin(), myvector->rend());
      MyVector::iterator it = myvector->begin();
      for (; it <myvector->end(); it++){
          sDrive &tmp = *it;          
          MyVector1::iterator it1 = tmp.m_files->begin();
          std::wcout << (*it1).GetName() << std::endl;
      }
      //When done, destroy the vector from the segment
      segment.destroy<MyVector>("MyVector");
      _getch();
   }

   return 0;
}

проблема возникла, хоть этот вариант и рабочий, но если данные на русском языке, то при чтении общей памяти вместо русских букв кракозяблы или вообще пустые строки, с английскими буквами все наоборот. А в первом приложении с русскими буквами все норм, хотя по идее в той же памяти расположены, можно эту проблему как то решить?

P.S. и что с сериализацией все-таки делать?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)