Ctypes:“将声明传递给使用sprintf的dll函数的指针时,“调试断言失败”(字符串!= NULL)

问题描述 投票:2回答:1

我正在尝试为预写的DLL文件使用Ctypes编写Python包装器,但一直在处理指针问题。

具体地说,已编译到DLL中的C ++函数的简化示例是:

double compute_result(double var1, double var2, char *output_message1, char *output_message2){
    // Computational steps are all here, e.g.
    double result = var1 + var2;

    // then an information message is passed to the output_message1 & 2 location
    sprintf(output_message1, "useful output message 1");
    sprintf(output_message2, "useful output message 2");

    return(result);
}

为了使用ctypes封装它,我尝试如下定义适当的restype和argtype。 C ++代码没有为输出消息指针指定大小,因此我假设我不必使用ctypes。

dll = ctypes.WinDLL("MyDLL.dll")
f = dll.compute_result
f.restype = c_double
f.argtypes = [c_double, c_double, POINTER(c_char), POINTER(c_char)]

然后我尝试使用以下命令在Python中调用代码:

# Imports
import ctypes
from ctypes import c_double, c_char, POINTER, addressof, cast

# Input variables
var1 = 1.1
var2 = 2.2

# Create string buffers to hold output message, then convert address to a pointer to pass to dll function
size = 1024  # we know output messages will be shorter than 1024 characters
buf1 = ctypes.create_string_buffer(size)
buf2 = ctypes.create_string_buffer(size)

f(var1, var2, cast(addressof(buf1), POINTER(c_char)), cast(addressof(buf2), POINTER(c_char)))

不幸的是,执行时显示对话框错误,说:

"Debug Assertion Failed!"

Program: ...somepath_on_my_computer\python.exe
File: ...somepath_on_my_computer\sprintf.c
Line: 110

Expression: (string != NULL)

我知道这意味着我的指针存在一些错误,其中sprintf也打算写入输出消息,但是我看不出到底是什么错误。有办法解决这个问题吗?还是我处理指针不正确?谢谢!

python c++ pointers pass-by-reference ctypes
1个回答
0
投票

列出[Python 3.Docs]: ctypes - A foreign function library for Python

buf1buf2(在底层[[C中))被视为数组,因此它们已经是地址。

摆脱

addressof,因为它将触发Undefined Behavior(检查[SO]: C function called from Python via ctypes returns incorrect value (@CristiFati's answer))。

尝试:

f(var1, var2, cast(buf1, POINTER(c_char)), cast(buf2, POINTER(c_char)))

有关更高级的示例,请检查[SO]: How can i cast a double pointer ctype to numpy array? (@CristiFati's answer)
© www.soinside.com 2019 - 2024. All rights reserved.