2013-06-09 3 views
2

У меня есть следующий код:повышение питон не может получить доступ к ИОС частный пункт

//test.cpp 
#include <Physical_file.h> 
#include <boost\python.hpp> 

using namespace boost::python; 
using namespace FMS_Physical; 


BOOST_PYTHON_MODULE(python_bridge) 
{ 
    class_<Physical_file>("pf") 
     .def("pcreate", &Physical_file::pcreate) 
    ; 
} 

//physical_file.h 
#include <fstream> 
#include "tools.h" 
using namespace std; 

#define FMS_lvl0_DLL_API __declspec(dllexport) 

namespace FMS_Physical 
{ 
    const int BLOCK_OFFSET = 20 + 4; 
    const string SUFFIX(".hash"); 

    struct block 
    { 
     unsigned int BlockNr; 
     char filler[20]; 
     char data[1024 - BLOCK_OFFSET]; 
    }; 

    class Physical_file 
    { 
    public: 
     fstream filefl; 
     string workingDir; 
     string fileName; 
     int fileSize; 
     block currBlock; 
     block FHBuffer; 
     bool opened; 
     string openMode; 

     /************ 
     functions 
     ************/ 

     FMS_lvl0_DLL_API Physical_file(void); 
     FMS_lvl0_DLL_API Physical_file(string &FileName, int FileSize, string &Dir = getCurrentPath()); 
     FMS_lvl0_DLL_API Physical_file(string &FileName, string &Type, string &Dir = getCurrentPath()); 

     FMS_lvl0_DLL_API ~Physical_file(void); 

     void FMS_lvl0_DLL_API pcreate(string &Name, int Size = 1000, string &Dir = getCurrentPath()); 
     void FMS_lvl0_DLL_API pdelete(void); 
     void FMS_lvl0_DLL_API popen(string &name, string &OpenMode = string("I"), string &Dir = getCurrentPath()); 
     void FMS_lvl0_DLL_API pclose(void); 

     void FMS_lvl0_DLL_API seekToBlock(unsigned int BlockNr); 

     void FMS_lvl0_DLL_API WriteBlock(void); 
     void FMS_lvl0_DLL_API ReadBlock(void); 
     void FMS_lvl0_DLL_API WriteFH(void); 
     void FMS_lvl0_DLL_API ReadFH(void); 

    }; 
} 

//physical_file.cpp 
void Physical_file::pcreate(string &Name, int Size, string &Dir) 
{ 
    if (Dir.compare("") == 0) 
     Dir = getCurrentPath(); 
    string fileFullName = Dir + '\\' + Name + SUFFIX; 
    this->filefl.open(fileFullName.c_str(),ios::in | ios::binary); 
    if (filefl.is_open()) 
    { 
     throw new exception((string("in function Physical_file::pcreate, file:") + fileFullName + " exists.").c_str()); 
    } 
    try{ 
     this->filefl.open(fileFullName.c_str(),ios::binary | ios::out); 
     this->opened = true; 
     this->seekToBlock(0); 
     this->currBlock.BlockNr = 0; 
     for (int i = 0; i < Size; i++) 
     { 
      for (int j = 0; j < sizeof(currBlock.data); j++) 
       this->currBlock.data[j] = 0; 
      for (int j = 0; j < sizeof(currBlock.filler); j++) 
       this->currBlock.filler[j] = 0; 
      this->WriteBlock(); 
     } 

     this->pclose(); 

     this->fileName = Name; 
     this->workingDir = Dir; 
     this->fileSize = Size; 
    } 
    catch(exception e) 
    { 
     throw new exception("in Physical_file::pcreate \n" + *e.what()); 
    } 
} 
Physical_file::Physical_file(void) 
{ 
    this->fileName = string(""); 
    this->workingDir = string(""); 
    this->opened = false; 
} 

(есть некоторый код, я думаю, что его не имеет отношения к проблеме)

при попытке компиляции I получите следующую ошибку:

error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>' 

Может ли кто-нибудь объяснить, почему эта проблема возникает и как ее исправить?

(я компиляции с помощью VS2010, python27 и C++ увеличить LIBS)

файлы physical_file.cpp и physical_file.h компилируются в DLL используется test.cpp

+0

Пожалуйста, не используйте 'std :: string (" ")'. Просто используйте 'std :: string()'. Конструктор по умолчанию намного эффективнее инициализации даже из пустого литерала (по крайней мере, на GCC/libstdC++). –

ответ

3

По умолчанию, форсирует .Python автоматически зарегистрирует конверсии to_python для открытых типов, например Physical_file. Таким образом, Boost.Python требует, чтобы эти типы были скопируемыми. В этом случае Physical_file не подлежит копированию его filefl членов принадлежит к типу, который не подлежит редактированию: fstream.

Чтобы решить эту проблему, либо:

  • Определить копию/владения семантику filefl, и управлять ею с помощью объекта держателя. Например, boost::shared_ptr.
  • Подавление автоматической регистрации конверсий python путем предоставления boost::noncopyable в качестве аргумента шаблона при экспонировании класса Physical_file.

    BOOST_PYTHON_MODULE(python_bridge) 
    { 
        boost::python::class_<Physical_file, boost::noncopyable>("pf") 
        .def("pcreate", &Physical_file::pcreate) 
        ; 
    } 
    

Для получения дополнительных возможностей при экспонировании на C++ класса на Python, обратитесь к документации boost::python::class_.

+0

Я попробовал второе решение, и скомпилированный код. Импорт dll в python также отлично работает, но 'pf' не определен. Есть идеи? – elyashiv

+0

Убедитесь, что имя библиотеки соответствует имени модуля, предоставленному 'BOOST_PYTHON_MODULE'. Кроме того, убедитесь, что «import» загружает ожидаемый модуль (имя конфликтует, а не «PYTHONPATH» и т. Д.). Параметр [-vv] (http://docs.python.org/3.1/using/cmdline.html#cmdoption-trace-v) может помочь лучше понять, что загружается. –