我正在为 C++ 库实现一个基于 cython 的接口(interface)。我实现了一个回调系统,它适用于普通函数,但在传入绑定(bind)方法时会奇怪地失败。这是我的 cython 代码的一部分:
cdef extern from "VolumeHapticTool.h":
cdef cppclass HDButtonEvent:
bool isPressed()
unsigned int getButtonId()
Vec3[float] getPosition()
ctypedef void (*HDButtonCallback)(HDButtonEvent, void *)
cdef extern from "Scene.h":
cdef cppclass Scene:
Scene()
void setDrillButtonCallback( HDButtonCallback, void*)
cdef void pyHDButtonCallback(HDButtonEvent e, void *user_data):
print <object>user_data
(<object>user_data)( (e.isPressed(), e.getButtonId(), topy_vec3f(e.getPosition())) )
cdef class pyScene:
cdef Scene * m_scene
def __init__(self):
self.m_scene = new Scene()
def __del__(self):
del self.m_scene
def setDrillButtonCallback(self, func):
print func
self.m_scene.setDrillButtonCallback(pyHDButtonCallback, <void*>func)
我是这样调用它的:
class RenderCanvas(GLCanvas):
def __init__(self, parent):
self.scene = cybraincase.pyScene()
self.scene.setDrillButtonCallback(self.OnDrillButtonPress)
def OnDrillButtonPress(self, event):
print event
最初运行此代码时,打印如下:
<bound method RenderCanvas.OnDrillButtonPress of <UI.RenderCanvas; proxy of <Swig Object of type 'wxGLCanvas *' at 0x42b70a8> >>
这似乎是正确的。问题是当回调被触发时,它被打印出来:
<bound method Shell.readline of <wx.py.shell.Shell; proxy of <Swig Object of type 'wxStyledTextCtrl *' at 0x3a12348> >>
正在调用一个完全不同的绑定(bind)方法。但是,当我制作 OnDrillButtonPress静态方法,
<function OnDrillButtonPress at 0x042FC570>
在初始化和触发调用时打印。
将绑定(bind)方法保存为 void* 是否不兼容?
最佳答案
感谢 Stefan Behnel 和 Mark Florisson 在 cython 讨论组中的评论,问题是对我的绑定(bind)方法的引用超出范围并被垃圾收集。
解决方案是这样做:
cdef class pyScene:
cdef Scene * m_scene
cdef object drill_button_func
def setDrillButtonCallback(self, func):
self.m_scene.setDrillButtonCallback(pyHDButtonCallback, <void*>func)
self.drill_button_func = func
通过在类中保留对绑定(bind)方法的引用,在它停止使用之前不会被清理。
关于python - Cython 回调适用于函数,但不适用于绑定(bind)方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7326762/
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje
它不等于主线程的binding,这个toplevel作用域是什么?此作用域与主线程中的binding有何不同?>ruby-e'putsTOPLEVEL_BINDING===binding'false 最佳答案 事实是,TOPLEVEL_BINDING始终引用Binding的预定义全局实例,而Kernel#binding创建的新实例>Binding每次封装当前执行上下文。在顶层,它们都包含相同的绑定(bind),但它们不是同一个对象,您无法使用==或===测试它们的绑定(bind)相等性。putsTOPLEVEL_BINDINGput
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我已经在Sinatra上创建了应用程序,它代表了一个简单的API。我想在生产和开发上进行部署。我想在部署时选择,是开发还是生产,一些方法的逻辑应该改变,这取决于部署类型。是否有任何想法,如何完成以及解决此问题的一些示例。例子:我有代码get'/api/test'doreturn"Itisdev"end但是在部署到生产环境之后我想在运行/api/test之后看到ItisPROD如何实现? 最佳答案 根据SinatraDocumentation:EnvironmentscanbesetthroughtheRACK_ENVenvironm
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法
当我使用has_one时,它工作得很好,但在has_many上却不行。在这里您可以看到object_id不同,因为它运行了另一个SQL来再次获取它。ruby-1.9.2-p290:001>e=Employee.create(name:'rafael',active:false)ruby-1.9.2-p290:002>b=Badge.create(number:1,employee:e)ruby-1.9.2-p290:003>a=Address.create(street:"123MarketSt",city:"SanDiego",employee:e)ruby-1.9.2-p290