0

C++ that creates string:

#include <iostream>
#include <string>

using namespace std;

extern "C" {
    string getchars() {
        string output = "";
        char letters[4] = { 'A', 'G', 'T', 'C' };
        for (int i = 0; i < 10000000; i++) {
            output += letters[rand() % 4];
        }
        return output.c_str();
    }

}

Python code that should return string generated in C++:

from ctypes import cdll
lib = cdll.LoadLibrary('mylib.so')
print(lib.getchars())

And it returns different numbers like 18806352, What should I do to return normal string? In C++ This functions works well

14
  • string getchars should be char *getchars, since that's what c_str() returns. Commented Jun 12, 2020 at 7:39
  • @Barmar That would return a pointer to a local . Commented Jun 12, 2020 at 7:41
  • The string returned by c_str() becomes invalid when the std::string is destroyed. Since output is destroyed when the function returns, you can't return output.c_str(). Commented Jun 12, 2020 at 7:41
  • I think you need allocate a dynamic C string and copy output.c_str() to it, then return that pointer. Commented Jun 12, 2020 at 7:43
  • @Barmar I have no idea how to do it, I'd be grateful if you write a bit of code how could I do it and why Commented Jun 12, 2020 at 7:45

2 Answers 2

2

Have a look at this discussion. This issue seems a lot similar with How to return char ** from C++ and fill it in a list in Python using ctypes?

It appears you need to specify the return type of the fuction in cdll. So you need to define the result type before calling the method.

I think this should work. Otherwise have a closer look to: https://docs.python.org/2/library/ctypes.html

[EDITED]

  • C++ implementation of file test.cpp (implementation of @Barmar):
#include <iostream>
#include <string>
#include <cstring>

using namespace std;

extern "C" char * getchars() {
    string output = "";
    char letters[4] = { 'A', 'G', 'T', 'C' };
    for (int i = 0; i < 10000000; i++) {
        output += letters[rand() % 4];
    }
    char *return_string = new char[output.length() + 1];
    strcpy(return_string, output.c_str());
    return return_string;
}
  • Compilation:
g++ -std=c++11 -Wall -Wextra -pedantic -c -fPIC test.cpp -o test.o
g++ -shared test.o -o test.so
  • Python file test.py:
from ctypes import cdll, c_char_p
lib = cdll.LoadLibrary('./test.so')
lib.getchars.restype = c_char_p
result = lib.getchars()
print(result)

Python version 3.7.4

This should work.

Sign up to request clarification or add additional context in comments.

9 Comments

now my lib.getchars() (after print(...)) prints me <__main__.LP_c_char_p object at 0x00FD2760>, how can I get the value?
Try using lib.getchars().value
lib.getchars().value and lib.getchars().values doesnt work
As this is a python object it has a type and a value.
Be aware that you might need to allocate the data via a malloc or something. Because otherwise even if you return .c_str() at the end, the string object is already destroyed. So you need to allocate this data to give it to python and free it in python.
|
0

You need to return a C string, not a C++ std::string. You'll need to make a dynamic copy of the c_str() so it will have lifetime past the function that created it.

extern "C" {
    char * getchars() {
        string output = "";
        char letters[4] = { 'A', 'G', 'T', 'C' };
        for (int i = 0; i < 10000000; i++) {
            output += letters[rand() % 4];
        }
        char *return_string = new char[output.length() + 1];
        strcpy(return_string, output.c_str());
        return return_string;
    }
}

5 Comments

'strdup' was not declared in this scope
It's two lines of trivial code to emulate, I added it to the answer.
did what you've wrote, included #include <string.h> #include <stdlib.h>, .so object created, but in python returns number anyway.. Did you tried it yourself? Maybe it will make some sence in the case it work for you or I missed sth
@WhoAmI i suppose python still prints the value of the pointer instead of the string
I assumed that ctypes would do the appropriate conversion to Python string.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.