为啥 sip 在使用 char * 时会抱怨意外类型“str”?

Posted

技术标签:

【中文标题】为啥 sip 在使用 char * 时会抱怨意外类型“str”?【英文标题】:Why does sip complain about unexpected type 'str' when using a char *?为什么 sip 在使用 char * 时会抱怨意外类型“str”? 【发布时间】:2020-10-21 12:42:41 【问题描述】:

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

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

我的假设是,使用 char *(就像在原始教程中一样)对于 sip 来说会“更容易”,我错过了什么?

我的 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]='\0';
    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'

感谢您的回答!

再见约翰尼

【问题讨论】:

请edit您的问题包含完整和完整的错误。如果有对文件和行的引用,请在该文件和该行中添加注释以显示错误的位置。 抱歉忘记了测试文件和错误信息 【参考方案1】:

简而言之,Python2 默认使用 str-type 和 python3 byte-type,所以我不得不更改 python3 的默认编码。

我找到了相关详情here

编码

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

指的是编码字符或以'\0'结尾的编码字符串 指定的编码。编码可以是“ASCII”、“Latin-1”、 “UTF-8”或“无”。 “无”的编码意味着相应的 参数引用未编码的字符或字符串。

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;
;

现在一切正常。

【讨论】:

以上是关于为啥 sip 在使用 char * 时会抱怨意外类型“str”?的主要内容,如果未能解决你的问题,请参考以下文章

为啥IE在设置innerHTML时会出现意外错误

为啥快速跳转到另一个页面时会出现意外空间

编写 if-else 编译器时会抱怨,但简而言之却没有,为啥? [复制]

为啥在将 malloc() 的指针分配给 char* 时会出现段错误?

为啥以 const char* 返回时会在此处创建临时字符串? [Stroustrup 的书例]

为啥当我使用 Cygwin X11 ssh 时,Vista 会抱怨一个死进程,我该如何让它关闭?