Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[QUESTION] How to write the binding code for a c++ function that takes char * and return a std::string #2615

Closed
ruiyang00 opened this issue Oct 22, 2020 · 8 comments

Comments

@ruiyang00
Copy link

rc4-2
rc4-1
Hello All, I have a cipher function inside the RC4 class that takes char* and returns std::string. I am wondering how should I write

the binding code. Thank you!!! I am trying return the string to python code. I have searched the Issues, I do not see any solution to my situation!!!

@bstaletic
Copy link
Collaborator

Pybind doesn't support pointers-as-arrays in bindings. Wrap that function call in a lambda that:

  • takes a py::str or py::bytes
  • extracts the char* with C API
  • calls cipher

@YannickJadoul
Copy link
Collaborator

@bstaletic I thought there was an exception for char * and const char * conversions from str (and maybe bytes)?

What's the error you get?

@ruiyang00
Copy link
Author

Below is my c++ code:

class RC4{
          
           char* cipher(char *text) {
                int i = 0;
                int j = 0;
                 char* ciphertext = new char[strlen(text)];
 
                for(size_t n = 0, len = strlen(text); n < len; n++) {
                     i = (i + 1) % N;
                     j = (j + S[i]) % N;

                     swap(&S[i], &S[j]);

                     int rnd = S[(S[i] + S[j]) % N];
               
                     std::cout<<"This is rnd: "<< rnd<< "\n";
            
                     ciphertext[n] = rnd ^ text[n];    

                  }
                  return ciphertext;
            }

}

below is my binding code:

PYBIND11_MODULE(example, m) {
py::class_<RC4>(m, "RC4")
        .def(py::init<>())
        .def("cipher", [](RC4 &self) -> py::bytes{
            return py::bytes(self.cipher())
        }); 
}

I am getting an error

rc4-3

@YannickJadoul
Copy link
Collaborator

@ruiyang00, well, if you read the error, it says you need to pass an argument to the RC4::cipher function. And you need a semicolon. These are plain C++ errors, unrelated to pybind11.

@ruiyang00
Copy link
Author

@YannickJadoul @rolandd @dekken
Really appreciate your guys time!
I am very new to pybind11. I do not know how to intercept the args passed from python to C++.
in python

r = RC4();
r.cipher("hello");

In pybind11:
How should I get the hello in pybind11 binding and pass "hello" string to my C++ cipher()?
becuase there was a issue with the utf-8 encoding between C++ and python. I read the pybind11 documentation, but there isn't much info that fit my situation.

@YannickJadoul
Copy link
Collaborator

I read the pybind11 documentation, but there isn't much info that fit my situation.

https://pybind11.readthedocs.io/en/stable/basics.html#creating-bindings-for-a-simple-function

all details regarding the function’s parameters and return value were automatically inferred using template metaprogramming.

I.e., make sure the function (in the form of a lambda, in your case) you're binding takes a parameter of the right type.

pybind11 automatically converts these types for you: https://pybind11.readthedocs.io/en/stable/advanced/cast/strings.html

@ruiyang00
Copy link
Author

@YannickJadoul thank you! I think we can close this Issue!

@YannickJadoul
Copy link
Collaborator

Thanks for letting me know, @ruiyang00! :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants