【问题标题】:Cannot read 'const char*' from python using ctypes无法使用 ctypes 从 python 读取'const char *'
【发布时间】:2021-12-04 13:19:29
【问题描述】:

我在 c++ 动态库中有一个简单的函数,它返回 const char* 值。该值是从string 类型分配的,如代码所示。我想在 python 脚本中使用 ctypes 读取函数的返回值:

C++

#include "pch.h"
#include <string>

#define EXPORT __declspec(dllexport)

extern "C" 
{
    EXPORT const char* sayHello()
    {
        std::string str = "hello world";
        const char* chptr = str.c_str();
        return chptr;
    }
}

Python

from ctypes import *

lib = CDLL("c:\\mysource\\mylib.dll")

lib.sayHello.restype = c_char_p

buff = lib.sayHello()

print(buff)

使用此代码,我在 python 中得到结果:

b''

但是当我更改我的 cpp 文件而不是使用string 类型和使用c_str() 的转换时,我将"hello world" 直接分配给const char*,它可以正常工作:

EXPORT const char* sayHello()
{
    const char* chptr = "hello world";
    return chptr;
}

...我在 python 中得到结果:

b'hello world'

为什么在使用 string 变量时,我在 python 中收到一个空条目,但在仅使用 const char* 时,它按预期工作?

【问题讨论】:

  • 您的第一个版本的sayHello 返回一个悬空指针。 std::string 对象拥有它指向的内存,当std::string 对象超出范围时,该内存将被释放。
  • ctypes 用于 C。对于 C++,请使用 pybind11

标签: python c++ ctypes


【解决方案1】:

当您到达功能块的末尾时,您的字符串正在破坏 - 相关 const char * 的内存正在被释放。

    EXPORT const char* sayHello()
    {
        std::string str = "hello world";
        const char* chptr = str.c_str(); // points to memory managed by str
        return chptr; // str gets destructed! This pointer points to dealloced memory
    }

在您的另一个示例中,const char * 指向一个字符串文字,它可能在 .rodata 段中,因此将超出函数的范围。

EXPORT const char* sayHello()
{
    const char* chptr = "hello world"; // String literal
    return chptr; // Underlying memory isn't deallocated
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-16
    • 2022-07-29
    • 1970-01-01
    • 1970-01-01
    • 2013-10-08
    • 1970-01-01
    相关资源
    最近更新 更多