从ctypes回调返回的正确指针类型是什么? [英] What is the correct pointer type to return from a ctypes callback?

查看:239
本文介绍了从ctypes回调返回的正确指针类型是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ctypes回调函数,该回调函数从dll中获取指向两个双精度数的指针,并返回指向.dll的两个双精度数的指针.第一部分工作正常,但是经过大量测试和研究,回调后我仍然无法获得正确的指针以返回到.dll.

I have a ctypes callback that takes a pointer to two doubles from the dll and returns a pointer to two doubles back to the .dll. The first part works correctly, but after a lot of testing and research, I still can't get the correct pointer to return to the .dll after the callback.

这是ctypes回调代码:

Here's the ctypes callback code:

from scipy.integrate import dblquad
import ctypes

LibraryCB = ctypes.WINFUNCTYPE(ctypes.py_object, ctypes.POINTER(ctypes.c_double))

def LibraryCall(ptr):
    n = ctypes.cast(ptr,ctypes.POINTER(ctypes.c_double))
    x = n[0] #Value = 83.0
    y = n[1] #Value = 30.0
    area = dblquad(lambda x, y: x*y, 0, 0.5, lambda x: 0, lambda x: 1-2*x)
    return_val = area[0], area[1]
    return (return_val)

lib_call = LibraryCB(LibraryCall)

lib_call = ctypes.cast(lib_call,ctypes.POINTER(ctypes.c_longlong))

我使用ctypes.py_object作为返回的指针类型,因为所有其他指针类型都返回一个错误,该错误不是回调的有效指针类型.

I used ctypes.py_object as the pointer type to return because all other pointer types return an error that it's not a valid pointer type for a callback.

指针返回到dll,但是提取的值不匹配,这表明我没有正确的指针类型.

The pointer returns to the dll, but the values extracted do not match, which suggests that I don't have the correct pointer type.

我还尝试将返回值强制转换为这样的指针:rv = ctypes.cast(return_val,ctypes.POINTER(ctypes.c_double)),然后返回该值,但这没有用.

I also tried casting the return value to a pointer like this: rv = ctypes.cast(return_val,ctypes.POINTER(ctypes.c_double)), and returning that instead, but that didn't work.

这是调用dll和回调的相关ctypes代码:

Here is the relevant ctypes code that calls the dll and the callback:

CA_data1 = (ctypes.c_double * len(data1))(*data1)
CA_data2 = (ctypes.c_double * len(data2))(*data2)
hDLL = ctypes.WinDLL("C:/NASM_Test_Projects/SciPy_Test/SciPy_Test.dll")
CallName = hDLL.Main_Entry_fn
CallName.argtypes = [ctypes.POINTER(ctypes.c_double),ctypes.POINTER(ctypes.c_double),ctypes.POINTER(ctypes.c_double),ctypes.POINTER(ctypes.c_longlong)]
CallName.restype = ctypes.c_double

ret_ptr = CallName(CA_data1,CA_data2,length_array_out,lib_call)

非常感谢您提供有关解决此问题的任何想法.

Thanks very much for any ideas on how to solve this.

推荐答案

DLL代码必须直接处理Python对象.您不能简单地将Python对象转换为ctypes指针.如果可以更改DLL代码,最简单的方法是使用输入/输出参数:

The DLL code would have to deal directly with Python objects. You can't simply cast a Python object to a ctypes pointer. The easiest way to do what you want if you can change the DLL code is to use an input/output parameter:

test.c

#include <stdio.h>

typedef void (*CALLBACK)(double*);

__declspec(dllexport) void function(CALLBACK callback)
{
    double param[2] = {1.5, 2.5};
    callback(param);
    printf("%lf %lf\n",param[0],param[1]);
}

test.py

from ctypes import *

CALLBACK = PYFUNCTYPE(None,POINTER(c_double))

@CALLBACK
def LibraryCB(data):
    x = data[0]
    y = data[1]
    print(x,y)
    data[0] *= 2
    data[1] *= 2

dll = CDLL('test')
dll.function.argtypes = [CALLBACK]
dll.function.restype = None

cb = CALLBACK(LibraryCB)

dll.function(cb)

输出

1.5 2.5
3.000000 5.000000

这篇关于从ctypes回调返回的正确指针类型是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆