【问题标题】:ctypes - function only returns empty stringctypes - 函数只返回空字符串
【发布时间】:2018-12-02 00:30:49
【问题描述】:

我在使用 ctypes 调用应该返回字符串的 C++ 库(用 extern C 包装)中的函数时遇到问题。我很确定我已经为 ctypes 接口正确设置了我的 argtypes 和 restype 到一个应该返回字符串的函数中,但无论如何我只会得到一个空字符串作为返回的结果。

C++ 代码:

const char* disasmC_PEProgram_getSections(PEProgram *p) {
    return p->getSections().c_str();
}

Python 代码:

lib.disasmC_PEProgram_getSections.argtypes = [ctypes.c_void_p]
lib.disasmC_PEProgram_getSections.restype = ctypes.c_char_p
resultStr = lib.disasmC_PEProgram_getSections(self.peProgram_p)

# Displays empty string for resultStr!
print "Result: %s" % (resultStr,) 

【问题讨论】:

  • 打印结果:%s" % (resultStr.value)?

标签: python ctypes


【解决方案1】:

我的猜测是从disasmC_PEProgram_getSections() 返回的值是一个局部变量或包含空值或其他东西。如果您需要更具体的帮助,请提供MCVE

这是我的 MCVE,它显示您的 Python 代码是正确的。请注意,我的 C++ 代码返回对对象中字符串的引用,以确保字符串的生命周期持续到对象被销毁。

test.cpp

#include <string>
using namespace std;

#define API __declspec(dllexport) // Windows-specific export

class PEProgram
{
    string section;
public:
    PEProgram() : section("section") {}
    const string& getSections() const { return section; }
};

extern "C" {
    API PEProgram* PEProgram_new() { return new PEProgram(); }
    API void PEProgram_delete(PEProgram* p) { delete p; }
    API const char* disasmC_PEProgram_getSections(PEProgram *p) {
        return p->getSections().c_str();
    }
}

test.py

#!python36
import ctypes

lib = ctypes.CDLL('test')
lib.PEProgram_new.argtypes = None
lib.PEProgram_new.restype = ctypes.c_void_p
lib.PEProgram_delete.argtypes = [ctypes.c_void_p]
lib.PEProgram_delete.restype = None

p = lib.PEProgram_new()

lib.disasmC_PEProgram_getSections.argtypes = [ctypes.c_void_p]
lib.disasmC_PEProgram_getSections.restype = ctypes.c_char_p
resultStr = lib.disasmC_PEProgram_getSections(p)

# Displays empty string for resultStr!
print(f'Result: {resultStr}')

lib.PEProgram_delete(p)

输出

Result: b'section'

请注意,如果我的班级是:

class PEProgram
{
public:
    string getSections() const { return "section"; }
};

然后我得到 b'' 作为 Python 中的值。这是因为disasmC_PEProgram_getSections 返回的字符串现在是一个临时值,在函数disasmC_PEProgram_getSections 返回后被销毁。现在返回的const char* 指向已释放的内存,并且会发生未定义的行为。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-09
    • 1970-01-01
    • 2016-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多