- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
这是我想要做的一个简化示例。假设我在 test.h 中有以下 C++ 代码
double f(double x);
double myfun(double (*f)(double x));
import test
f = test.f
myfun(f)
TypeError: in method 'myfun', argument 1 of type 'double (*)(double)'
%typemap double f(double);
最佳答案
注意:这个答案有很长的部分是关于变通方法的。如果您只是想使用此方法,请直接跳至解决方案 5。
问题
您已经遇到了这样一个事实,即在 Python 中一切都是对象。在我们考虑修复问题之前,首先让我们了解正在发生的事情。我已经创建了一个完整的示例来使用头文件:
double f(double x) {
return x*x;
}
double myfun(double (*f)(double x)) {
fprintf(stdout, "%g\n", f(2.0));
return -1.0;
}
typedef double (*fptr_t)(double);
fptr_t make_fptr() {
return f;
}
make_fptr()
返回一些东西给 Python 的函数我们知道将被包装成一个函数指针。
%module test
%{
#include "test.h"
%}
%include "test.h"
swig2.0 -Wall -python test.i && gcc -Wall -Wextra -I/usr/include/python2.6 -std=gnu99 -shared -o _test.so test_wrap.c
test.f
的类型和调用结果的类型
test.make_fptr())
:
Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> type(test.f)
<type 'builtin_function_or_method'>
>>> repr(test.f)
'<built-in function f>'
>>> type(test.make_fptr())
<type 'SwigPyObject'>
>>> repr(test.make_fptr())
"<Swig Object of type 'fptr_t' at 0xf7428530>"
myfun(test.f)
不会工作。
test.make_fptr()
返回一个指向函数指针的 Python 句柄
f
.所以我们实际上可以调用:
f=test.make_fptr()
test.myfun(f)
%constant
. (通常这用于公开编译时常量,但本质上所有函数指针实际上都是最简单的形式)。
%module test
%{
#include "test.h"
%}
%constant double f(double);
%ignore f;
%include "test.h"
%constant
指令告诉 SWIG 包装
f
作为函数指针,而不是函数。
%ignore
需要避免有关看到同一标识符的多个版本的警告。
typedef
和
make_fptr()
函数)
Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> type(test.f)
<type 'SwigPyObject'>
>>> repr(test.f)
"<Swig Object of type 'double (*)(double)' at 0xf7397650>"
>>> test.f(0)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'SwigPyObject' object is not callable
test.f
从 Python 方面。这导致了下一个解决方案:
test.f
作为函数指针和内置函数。我们可以通过简单地使用
%rename
来做到这一点。而不是
%ignore
:
%{
#include "test.h"
%}
%constant double f(double);
%rename(f_call) f;
%include "test.h"
Python 2.6.6 (r266:84292, Dec 27 2010, 00:02:40)
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
>>> repr(test.f)
"<Swig Object of type 'double (*)(double)' at 0xf73de650>"
>>> repr(test.f_call)
'<built-in function f_call>'
test.f_call
的想法。或只是
test.f
取决于我想处理的上下文
f
当时。我们可以通过在 SWIG 接口(interface)中编写一些 Python 代码来实现这一点:
%module test
%{
#include "test.h"
%}
%rename(_f_ptr) f;
%constant double f(double);
%rename(_f_call) f;
%feature("pythonprepend") myfun %{
args = f.modify(args)
%}
%include "test.h"
%pythoncode %{
class f_wrapper(object):
def __init__(self, fcall, fptr):
self.fptr = fptr
self.fcall = fcall
def __call__(self,*args):
return self.fcall(*args)
def modify(self, t):
return tuple([x.fptr if isinstance(x,self.__class__) else x for x in t])
f = f_wrapper(_f_call, _f_ptr)
%}
test.f
成为这个包装器的一个实例。当它作为函数被调用时,它会传递调用。最后我们在
myfun
中插入一些额外的代码包装器来交换真正的函数指针而不是我们的包装器,注意不要改变任何其他参数(如果有的话)。
import test
print "As a callable"
test.f(2.0)
print "As a function pointer"
test.myfun(test.f)
%rename
,
%constant
和包装器实例创建,但我们无法真正摆脱使用
%feature("pythonprepend")
的需要我们到处将这些包装器传回 SWIG。 (如果可以透明地做到这一点,这远远超出了我的 Python 知识)。
swig -python -builtin
它根本行不通,因为首先没有要添加 Python 代码! (您需要将包装器的构造更改为:
f = f_wrapper(_test._f_call, _test._f_ptr)
,但这还不够)。
%module test
%{
#include "test.h"
%}
%{
static __thread PyObject *callback;
static double dispatcher(double d) {
PyObject *result = PyObject_CallFunctionObjArgs(callback, PyFloat_FromDouble(d), NULL);
const double ret = PyFloat_AsDouble(result);
Py_DECREF(result);
return ret;
}
%}
%typemap(in) double(*)(double) {
if (!PyCallable_Check($input)) SWIG_fail;
$1 = dispatcher;
callback = $input;
}
%include "test.h"
void*
用户数据参数以及回调的实际输入。在这些情况下,“userdata”可以是 Python 可调用的。
PyObject
向后工作并尝试找出它是哪个函数(如果有)的包装器:
%module test
%{
#include "test.h"
%}
%{
static __thread PyObject *callback;
static double dispatcher(double d) {
PyObject *result = PyObject_CallFunctionObjArgs(callback, PyFloat_FromDouble(d), NULL);
const double ret = PyFloat_AsDouble(result);
Py_DECREF(result);
return ret;
}
SWIGINTERN PyObject *_wrap_f(PyObject *self, PyObject *args);
double (*lookup_method(PyObject *m))(double) {
if (!PyCFunction_Check(m)) return NULL;
PyCFunctionObject *mo = (PyCFunctionObject*)m;
if (mo->m_ml->ml_meth == _wrap_f)
return f;
return NULL;
}
%}
%typemap(in) double(*)(double) {
if (!PyCallable_Check($input)) SWIG_fail;
$1 = lookup_method($input);
if (!$1) {
$1 = dispatcher;
callback = $input;
}
}
%include "test.h"
%typemap(constcode)
允许
%constant
用作方法和函数指针。事实证明,SWIG 已经支持这样做,这是我在阅读一些 SWIG 源代码时发现的。所以实际上我们需要做的很简单:
%module test
%{
#include "test.h"
%}
%pythoncallback;
double f(double);
%nopythoncallback;
%ignore f;
%include "test.h"
%pythoncallback
启用一些全局状态,导致后续函数被包装为可用于函数指针和函数!
%nopythoncallback
禁用那个。
-builtin
):
import test
test.f(2.0)
test.myfun(test.f)
%pythoncallback
.所以前四种解决方案大多只是作为定制 SWIG 接口(interface)的示例有用。
关于python - 如何使用 SWIG 包装在 python 中接收函数指针的 C++ 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22923696/
我有一个存储结构向量的应用程序。这些结构保存有关系统上每个 GPU 的信息,如内存和 giga-flop/s。每个系统上有不同数量的 GPU。 我有一个程序可以同时在多台机器上运行,我需要收集这些数据
我很好奇 MPI 中缺少此功能: MPI_Isendrecv( ... ); 即,非阻塞发送和接收,谁能告诉我其省略背后的基本原理? 最佳答案 我的看法是 MPI_SENDRECV存在是为了方便那些想
当我用以下方法监听TCP或UDP套接字时 ssize_t recv(int sockfd, void *buf, size_t len, int flags); 或者 ssize_t recvfrom
SUM:如何在 azure 事件网格中推迟事件触发或事件接收? 我设计的系统需要对低频对象状态(创建、启动、检查长时间启动状态、结束)使用react。它看起来像是事件处理的候选者。我想用azure函数
我正在 MPI 中实现一个程序,其中主进程(等级 = 0)应该能够接收来自其他进程的请求,这些进程要求只有根才知道的变量值。如果我按等级 0 进行 MPI_Recv(...),我必须指定向根发送请求的
我正在学习DX12,并在此过程中学习“旧版Win32”。 我在退出主循环时遇到问题,这似乎与我没有收到WM_CLOSE消息有关。 在C++,Windows 10控制台应用程序中。 #include
SUM:如何在 azure 事件网格中推迟事件触发或事件接收? 我设计的系统需要对低频对象状态(创建、启动、检查长时间启动状态、结束)使用react。它看起来像是事件处理的候选者。我想用azure函数
我想编写方法来通过号码发送短信并使用编辑文本字段中的文本。发送消息后,我想收到一些声音或其他东西来提醒我收到短信。我怎样才能做到这一点?先感谢您,狼。 最佳答案 这个网站似乎对两者都有很好的描述:ht
所以我正在用 Java 编写一个程序,在 DatagramSocket 和 DatagramPacket 的帮助下发送和接收数据。问题是,在我发送数据/接收数据之间的某个时间 - 我发送数据的程序中的
我是 Android 编程新手,我正在用 Java 编写一个应用程序,该应用程序可以打开相机拍照并保存。我通过 Intents 做到了,但看不到 onActivityResult 正在运行。 我已经在
我有一个套接字服务器和一个套接字客户端。客户端只有一个套接字。我必须使用线程在客户端发送/接收数据。 static int sock = -1; static std::mutex mutex; vo
我正在尝试使用 c 中的套接字实现 TCP 服务器/客户端。我以这样的方式编写程序,即我们在客户端发送的任何内容都逐行显示在服务器中,直到键入退出。该程序可以运行,但数据最后一起显示在服务器中。有人可
我正在使用微 Controller 与 SIM808 模块通信,我想发送和接收 AT 命令。 现在的问题是,对于某些命令,我只收到了我应该收到的答案的一部分,但对于其他一些命令,我收到了我应该
我用c设计了一个消息传递接口(interface),用于在我的系统中运行的不同进程之间提供通信。该接口(interface)为此目的创建 10-12 个线程,并使用 TCP 套接字提供通信。 它工作正
我需要澄清一下在套接字程序中使用多个发送/接收。我的客户端程序如下所示(使用 TCP SOCK_STREAM)。 send(sockfd,"Messgfromlient",15,0);
我正在构建一个真正的基本代理服务器到我现有的HTTP服务器中。将传入连接添加到队列中,并将信号发送到另一个等待线程队列中的一个线程。此线程从队列中获取传入连接并对其进行处理。 问题是代理程序真的很慢。
我正在使用 $routeProvider 设置一条类似 的路线 when('/grab/:param1/:param2', { controller: 'someController',
我在欧洲有通过 HLS 流式传输的商业流媒体服务器。http://europe.server/stream1/index.m3u8现在我在美国的客户由于距离而遇到一些网络问题。 所以我在美国部署了新服
我有一个长期运行的 celery 任务,该任务遍历一系列项目并执行一些操作。 任务应该以某种方式报告当前正在处理的项目,以便最终用户知道任务的进度。 目前,我的django应用程序和celery一起坐
我需要将音频文件从浏览器发送到 python Controller 。我是这样做的: var xmlHttp = new XMLHttpRequest(); xmlHttp.open( "POST",
我是一名优秀的程序员,十分优秀!