0

I'm trying to do integrate with python and c++ now and what I'm gonna do is using c++ function in python.

The feature of function is read all text in a text file.

I know I have to make c++ code to c style, so I made c++ code like below:

void ReadTextFile(string fileName)
{
    string str;
    string line;
    
    ifstream file(fileName);
    while(getline(file, line))
    {
        vector<string> result = split(line, ':');
        if (result.size() > 1)
        {
            result[1].erase(std::remove(result[1].begin(), result[1].end(), ' '), result[1].end());
            cout << result[1] << endl;
        }
    }
}



extern "C" {
    void ReadTextFileCpp(string fileName) {return ReadTextFile(fileName);
}

So I can get right result what I want to when I just build this c++ file.

But the problem is when I build this cpp file to .so file and call this function in python file. this is what I call the function in python:

lib2 = cdll.LoadLibrary('./ReadTextFile.so')
lib2.ReadTextFileCpp('0166_405504.txt')

The error occurs when I call the ReadTextFile function and this is the error message.

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

Why this error occurs only when I call in python?

p.s) I have changed 'std::string' to 'const char*'. This code runs but it doesn't get inside of while loop.

void ReadTextFile(const char* fileName)
{
    string str;
    string line;
    
    ifstream file(fileName);
    while(getline(file, line))
    {
        vector<string> result = split(line, ':');
        if (result.size() > 1)
        {
            result[1].erase(std::remove(result[1].begin(), result[1].end(), ' '), result[1].end());
            cout << result[1] << endl;
        }
    }
}



extern "C" {
    void ReadTextFileCpp(const char* fileName) {return ReadTextFile(fileName);
}
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Jacob
  • 101
  • 11
  • 3
    [You can't make an `extern "C"` function that accepts a C++ type like `std::string`](https://stackoverflow.com/a/9629265/364696) (some compiler implementations may allow it, but Python doesn't know how to call such things). To be legal `extern "C"`, it has to have a prototype (arguments and return values) that are C legal. The body of the function can do C++ things, but the *interface* must be C-legal. In this case that should be doable at least; just accept `const char*` instead of `std::string`. – ShadowRanger Jun 16 '22 at 02:37
  • I tried change parameter std::string to const char*, but it doesn't work as well... – Jacob Jun 16 '22 at 02:41
  • Have you read the `ctypes` docs? You need to declare the prototypes for the function, or it assumes everything is `int`s (which is kind of a problem when passing a pointer). It's also unclear what's `split` is here; it could hide all sorts of issues. I'd suggest trying to test this code purely in C++ with a debugger, to make sure it works there, before trying to interface to it with Python. – ShadowRanger Jun 16 '22 at 03:37
  • @ShadowRanger I've changed parameter to 'const char*' and it works right when I run in purely C++ with a debugger. But it doesn't get inside of while loop when I call the function in python. – Jacob Jun 16 '22 at 04:43
  • Did you define the `argtypes` and `restype` for the function at the Python layer? Again, read the `ctypes` docs, you can't just call a function by name and hope. – ShadowRanger Jun 16 '22 at 04:44
  • Use [pybind11](https://pybind11.readthedocs.io/en/stable/). – n. m. could be an AI Jun 16 '22 at 05:12
  • @ShadowRanger Of course you can make such a function. There is nothing in the C++ standard that prohibits it. Ctypes cannot call it, but it's called ctypes and not c++types for a reason. – n. m. could be an AI Jun 16 '22 at 05:15
  • I solved the problem. I've change python code 'lib2.ReadTextFileCpp('0166_405504.txt')' to 'lib2.ReadTextFileCpp("0166_405504.txt".encoode()). I refer to below. https://stackoverflow.com/questions/52916077/calling-c-function-from-python – Jacob Jun 17 '22 at 00:10

0 Answers0