-3

I changed the code one month ago and im stucking at the same error which i described below. I dont find a pretty simple example how to expose an fstream object with Boost.Python to Python to solve my explained problem

In short words i just want to expose a Class that contains an I/O object with functions write / open / close. In Pyton i want to do these steps:

  1. open File1
  2. open File2
  3. open File3
  4. write to File1
  5. write to File2
  6. write to File3
  7. close files

C/C++ Code

////// I N C L U D E S //////
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <boost/python.hpp>
#include <fstream>
#include <string.h>
////////////////////////////


using namespace std;

struct BoostXML_IO
{
    ofstream File;

    void writeFile(const string& strToWrite)
    {
        this->File.write(strToWrite.data(), strToWrite.size());
    }

    void openFile(const string& path)
    {
        this->File.open(path, ios::app);
    }

    void closeFile()
    {
        this->File.close();
    }

};


BOOST_PYTHON_MODULE(BoostXML_IO)
{
    using namespace boost::python;  
    class_<BoostXML_IO, boost::noncopyable>("BoostXML_IO")
      .def("writeFile", &BoostXML_IO::writeFile)
      .def("openFile", &BoostXML_IO::openFile)
      .def("closeFile", &BoostXML_IO::closeFile)
    ;
}

This code always compiles without an error but finally in Python i always get the following error when i try to invoke one of the functions in the prompt line.

ERROR code

>>> import BoostXML_IO
>>> File1 = BoostXML_IO
>>> File = BoostXML_IO.BoostXML_IO.openFileFailed to format the args
Traceback (most recent call last):
  File "C:\app\tools\Python25\Lib\site-packages\pythonwin\pywin\idle\CallTips.py", line 130, in get_arg_text
    argText = inspect.formatargspec(*arg_getter(fob))
  File "C:\app\tools\Python25\Lib\inspect.py", line 743, in getargspec
    raise TypeError('arg is not a Python function')
TypeError: arg is not a Python function
(

Thank you a lot in advance !

Flo
  • 155
  • 1
  • 11
  • You must have some kind of reason to believe there is a error. It would be wonderful if you would share what you have tried, and what went wrong. Does it compile? if not, what are the compiler errors? – M4rtini Jun 05 '14 at 10:28
  • @M4rtini sorry i forgot to add my error code of the command prompt – Flo Jun 05 '14 at 10:46
  • 2
    Mbeyond the compiler problems, you never declare ``myFile`` at the class level (only as a local in your open method), yet use it in every class method. That isn't going to work. You also declare ``strToWrite`` as a ``const char``, but then in your write method you make it an input parameter and declare it as ``const char *``. Beyond this type conflict, why not just make it a ``string``? – aruisdante Jun 05 '14 at 13:14
  • Please post the other error messages as well, specifically the line with information about which line in your code the error is originating from. Btw: You don't need the `this->` in front of `myFile`. – jasal Jun 06 '14 at 07:44
  • 1
    This is probably because the implicitly generated copy constructor of your struct tries to copy the `myFile` member. Copying a stream is not allowed, so compilation fails. Disable the copy constructor in your struct by adding `private: BoostXML_IO(const BoostXML_IO&);` – jasal Jun 06 '14 at 08:00
  • @jasal that doesn't worked for me – Flo Jun 10 '14 at 14:27
  • Where is the parameter in your `openFile` call? – jasal Jun 16 '14 at 12:42
  • @jasal i can't enter a parameter, because i got the error code after i entered a "(".. – Flo Jun 16 '14 at 12:54

1 Answers1

1

Your compile errors have nothing to do with Boost.Python. Start by including <string> and <ofstream> and add a using namespace std;. That should fix most of the errors you're getting. Then fix your struct declaration like so:

struct BoostXML_IO
{    
  void openFile(const string& path)
  {
    myfile.open(path);
  }
  void closeFile()
  {
    myfile.close();
  }
  void WriteToFile(const char* strToWrite)
  {
    myfile.write(strToWrite, strlen(strToWrite));
  }

private:
  ofstream myFile;
};

I also don't see a need for setting a readwrite reference to the strToWrite and path members when you pass them as parameters in openFile and WriteToFile.


EDIT What about this:

struct BoostXML_IO
{
    BoostXML_IO()
    {}

    void writeFile(const string& strToWrite)
    {
        File.write(strToWrite.data(), strToWrite.size());
    }

    void openFile(const string& path)
    {
        File.open(path, ios::out);
    }

    void closeFile()
    {
        File.close();
    }

private:
    BoostXML_IO(const BoostXML_IO&);
    BoostXML_IO& operator=(const BoostXML_IO&);

    ofstream File;
};


BOOST_PYTHON_MODULE(BoostXML_IO)
{
    using namespace boost::python;  
    class_<BoostXML_IO>("BoostXML_IO", init<>())
      .def("writeFile", &BoostXML_IO::writeFile)
      .def("openFile", &BoostXML_IO::openFile)
      .def("closeFile", &BoostXML_IO::closeFile)
    ;
}

I have no idea why you'd want to expose an ofstream to the python API. Same for the pathToFile variable which is kind of useless when specifying the file path in openFile. But I think I mentioned that already.

jasal
  • 1,044
  • 6
  • 14
  • i changed my code, but now i have a problem with boost.python. Because boost.python can't access my private declared class members. Can you give ma a simple example for my spefici I/O handling ? – Flo Jun 11 '14 at 11:25
  • i want to expose this because its much faster than equivalent python functions for writing one line to a file. I did some runtime measurements and ofstream.write() won the race. I also did a runtime measurement when i just exposed the write function to the python API. But as i mentionend i want 1 object for 1 file i'm writing to, because i have to access many times to these 3 files at my programm. – Flo Jun 11 '14 at 13:30
  • My question was why you would want to expose the `File` variable in your struct directly when you already have functions which duplicate the `ofstream` interface. – jasal Jun 11 '14 at 13:33
  • i don't know how its possible to access the files without ofstream File variable for writing to the file ? If you have any other solutions that contain my desired functionalities i would be very happy! – Flo Jun 11 '14 at 13:35
  • your solution don't works. Do you have another solution how i can expose a C++ class with a fstream member with boost.python? – Flo Jun 16 '14 at 11:45
  • No I don't have another solution because you don't even bother to tell us why the last one didn't work. – jasal Jun 16 '14 at 12:05
  • same problem with accessing private members. i have now a code that i can compile, but i have another problems now in python – Flo Jun 16 '14 at 12:11
  • finally you dont answer to my last change. I changed the question and described my problem above. – Flo Jul 23 '14 at 12:34
  • Where are the functions arguments to openFile in your call? – jasal Jul 24 '14 at 13:19
  • i got the error message when i try to enter "(", furthermore i cant enter the function arguments ? I thought the reason is that i block to copy the constructor of the ofstream object ? – Flo Jul 24 '14 at 13:35
  • You have not created an instance of BoostXML_IO in your python session. What happens when you do `file = BoostXML_IO()` and then `file.openFile("some/path")`? – jasal Jul 25 '14 at 07:53
  • I created an instance of BoostXML_IO. Afterwards when i want to invoke the function it will raise an Python Interpreter error (TypeError: arg is not a Python function). – Flo Aug 06 '14 at 07:27