[英]Cannot read 'const char*' from python using ctypes
I have a simple function in a c++
dynamic library which returns a const char*
value.我在
c++
动态库中有一个简单的函数,它返回一个const char*
值。 This value is assigned from a string
type as shown in the code.该值是从
string
类型分配的,如代码所示。 I want to read the returned value of the function in a python script using ctypes :我想使用ctypes在 python 脚本中读取函数的返回值:
#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;
}
}
from ctypes import *
lib = CDLL("c:\\mysource\\mylib.dll")
lib.sayHello.restype = c_char_p
buff = lib.sayHello()
print(buff)
Using this code, in python I get as a result:使用此代码,在 python 中我得到的结果是:
b''
But when I change my cpp file and instead of using the string
type and the conversion with c_str()
, I assign the "hello world"
directly into the const char*
, it works ok:但是当我更改我的 cpp 文件而不是使用
string
类型和转换c_str()
,我将"hello world"
直接分配给const char*
,它工作正常:
EXPORT const char* sayHello()
{
const char* chptr = "hello world";
return chptr;
}
... and I get as a result in python: ......我在python中得到了结果:
b'hello world'
Why when using a string
variable, I receive an empty entry in python, but when using just the const char*
, it works as expected?为什么在使用
string
变量时,我在 python 中收到一个空条目,但是当只使用const char*
,它按预期工作?
Your string is destructing as you reach the end of your function block - and the memory for the associated const char *
is getting freed.当您到达功能块的末尾时,您的字符串正在破坏 - 相关联的
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
}
In your other example, the const char *
points to a string literal, which is likely in the .rodata segment, and so will outlive the scope of the function.在您的另一个示例中,
const char *
指向一个字符串文字,它可能在 .rodata 段中,因此将超过函数的范围。
EXPORT const char* sayHello()
{
const char* chptr = "hello world"; // String literal
return chptr; // Underlying memory isn't deallocated
}
Both versions are wrong because the memory will be released once the sayHello
function has finished.两个版本都是错误的,因为一旦
sayHello
函数完成,内存就会被释放。
If you need to return a string you have 2 options:如果您需要返回一个字符串,您有 2 个选项:
ctypes.create_string_buffer
and copy the data to it through strcpy
ctypes.create_string_buffer
从 python 创建一个缓冲区,然后通过strcpy
将数据复制到它malloc
or something to reserve the memory without releasing it.malloc
什么的来保留内存而不释放它。 In this case you have to manually run free
once you're done or you'll have a memory leak.free
运行,否则会出现内存泄漏。 I would strongly recommend option 1.我强烈推荐选项 1。
Option 1 would look something like this:选项 1 看起来像这样:
#include "pch.h"
#include <string>
#define EXPORT __declspec(dllexport)
extern "C"
{
EXPORT void sayHello(char* buffer, int bufferSize)
{
std::string str = "hello world";
str.copy(buffer, bufferSize);
}
}
from ctypes import *
lib = CDLL("c:\\mysource\\mylib.dll")
lib.sayHello.restype = c_char_p
buffer_size = 32
buffer = create_string_buffer(buffer_size)
lib.sayHello(buffer, buffer_size)
print(buffer.value)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.