为什么 sip 在使用 char * 时会抱怨意外类型 'str'?

Why does sip complain about unexpected type 'str' when using a char *?

我正在尝试使用 sip 创建从 c++ 到 python 3.8 的 python 绑定。 I found a simple example here 并更新它以使其与我用 pip 安装的 sip 版本 5.4 一起使用。 Details can be found here

我将名称从 word 更改为 basicword,因为我用字符串重写并测试了 word 示例。为此,我必须编写一堆特定于 sip 的代码来导入字符串库,并且认为必须有更简单的方法。

我假设使用 char *(就像在原始教程中一样)对于 sip 来说是 'easier',我错过了什么?

我的 sip 文件 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;
};

我的 pyproject.toml 文件:

# 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 = ["."]

我的 basicword.h 文件:

#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

我的 basicword.cpp 文件:

#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]='[=14=]';
    return str;
}

我的档案test.py:

from basicword import Basicword

w = Basicword("reverse me") // -> error thrown here


if __name__ == '__main__':
    print(w.reverse())

错误信息:

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'

感谢您的回答!

再见约翰尼

简而言之 Python2 默认使用 str-type 和 python3 byte-type 所以我不得不更改 python3.

的默认编码

我找到了相关的细节here

Encoding

This string annotation specifies that the corresponding argument (which should be either char, const char, char * or const char *)

refers to an encoded character or '[=13=]' terminated encoded string with the specified encoding. The encoding can be either "ASCII", "Latin-1", "UTF-8" or "None". An encoding of "None" means that the corresponding argument refers to an unencoded character or string.

The default encoding is specified by the %DefaultEncoding directive. If the directive is not specified then None is used.

Python v3 will use the bytes type to represent the argument if the encoding is "None" and the str type otherwise.

Python v2 will use the str type to represent the argument if the encoding is "None" and the unicode type otherwise.

在 basicword.sip 中进行以下简单添加 ...

// Define the SIP wrapper to the basicword library.

%Module(name=basicword, language="C++")

%DefaultEncoding "UTF-8" // Missing Encoding!

class Basicword {

%TypeHeaderCode
#include <basicword.h>
%End

public:
    Basicword(const char *w);

    char *reverse() const;
};

现在一切正常。