I am trying to use sip to create python bindings from c++ to python 3.8. I found a simple example here and updated it to get it working with sip version 5.4 which I installed with pip. Details can be found here
I changed the names from word to basicword because I rewrote and tested the word example with strings. To do that I had to write a bunch of sip specific code to get the import of the string library working and thought there must be an easier way.
I was under the assumption, that using a char * (like in the original tutorial) would be 'easier' for sip, what am I missing?
My sip file basicword.sip:
// Define the SIP wrapper to the basicword library.
%Module(name=basicword, language="C++")
class Basicword {
%TypeHeaderCode
#include <basicword.h>
%End
public:
Basicword(const char *w);
char *reverse() const;
};
My pyproject.toml file:
# Specify sip v5 as the build system for the package.
[build-system]
requires = ["sip >=5, <6"]
build-backend = "sipbuild.api"
# Specify the PEP 566 metadata for the project.
[tool.sip.metadata]
name = "basicword"
# Configure the building of the basicword bindings.
[tool.sip.bindings.basicword]
headers = ["basicword.h"]
include-dirs = ["."]
libraries = ["basicword"]
library-dirs = ["."]
My basicword.h file:
#ifndef BASICWORD_H
#define BASICWORD_H
// Define the interface to the basicword library.
class Basicword {
private:
const char *the_word;
public:
Basicword(const char *w);
char *reverse() const;
};
#endif //BASICWORD_H
My basicword.cpp file:
#include "basicword.h"
#include <cstring>
Basicword::Basicword(const char *w) {
the_word = w;
}
char* Basicword::reverse() const {
int len = strlen(the_word);
char *str = new char[len+1];
for(int i = len-1;i >= 0 ;i--) {
str[len-1-i] = the_word[i];
}
str[len+1]='\0';
return str;
}
My file test.py:
from basicword import Basicword
w = Basicword("reverse me") // -> error thrown here
if __name__ == '__main__':
print(w.reverse())
The error message:
Traceback (most recent call last):
File "<path to testfile>/test.py", line 3, in <module>
w = Basicword("reverse me")
TypeError: arguments did not match any overloaded call:
Basicword(str): argument 1 has unexpected type 'str'
Basicword(Basicword): argument 1 has unexpected type 'str'
Thank you for your answer!
Bye Johnny
In short Python2 uses str-type by default and python3 byte-type so I had to change default encoding for python3.
I found the relevant detail here
With the following simple addition in basicword.sip ...
everything works now.