如何使用pythonnet在python侦听器中订阅.NET事件? [英] How to subscribe to a .NET event in a python listener using pythonnet?

查看:193
本文介绍了如何使用pythonnet在python侦听器中订阅.NET事件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Python使事件侦听器从FX交易应用程序中订阅 tick (价格)事件.原始应用程序是一个名为 MetaTrader4 的本地32位Windows应用程序.它没有任何API,因此 mtapi 桥已在.NET中设计为允许其他编程与之互动的语言.该应用程序定义了一些事件,其中两个是: QuoteUpdate QuoteUpdated .

I'm trying to make an event listener to subscribe to a tick (price) event from a FX trading application, using Python. The original application is a native 32-bit Windows app called MetaTrader4. This does not have any API, so the mtapi bridge has been designed in .NET to allow other programming languages to interact with it. The application has some events defined, two of which are: QuoteUpdate and QuoteUpdated.

所以我想使用 python.net编写一个侦听器( delegate ?).订阅此活动.但是由于我无法理解.NET代码是如何产生这些事件的,也无法理解如何正确使用 pythonnet ,因此无法使它正常工作.我还不断遇到错误:

So I would like to write a listener (delegate?) using python.net to subscribe to this event. But since I am not able to understand how the .NET code is producing these events, and neither how to properly use pythonnet, I have not been able to get this to work. I also keep running into the error:

TypeError:'EventBinding'对象不可调用

TypeError: 'EventBinding' object is not callable

使用Google谷歌搜索功能不会返回任何有用的信息,除了"FIXME"评论.

Googling this doesn't return anything useful, apart this "FIXME" comment.

这是我的代码:

import os, sys, clr
sys.path.append(r"C:\Program Files\MtApi")
asm = clr.AddReference('MtApi')
import MtApi as mt

res = 0

def printTick(symbol, ask, bid):
    print('Tick: Symbol: {}  Ask: {:.5f}  Bid: {:.5f}'.format(symbol, ask, bid))

# Setup .NET API bridge connection
mtc = mt.MtApiClient()
res = mtc.BeginConnect('127.0.0.1', 8222);

#--------------------------------------
# Register and use the listener
#--------------------------------------
# This does NOT work!
mtc.QuoteUpdate += printTick

#...

我的代码的意图应该很清楚.

The intention for my code should be clear.

问:接收到 QuoteUpdate .NET事件时如何激发我的监听器?

Q: How can I make my listener fire when receiving the QuoteUpdate .NET event?

供参考:

  • The .NET code in C# (from MtApiClient.cs look like this:
...
private void _client_QuoteUpdated(MTApiService.MtQuote quote) { 
    if (quote != null) { 
        QuoteUpdate?.Invoke(this, new MtQuoteEventArgs(new MtQuote(quote))); 
        QuoteUpdated?.Invoke(this, quote.Instrument, quote.Bid, quote.Ask); 
    } 
} 
...
public event MtApiQuoteHandler QuoteUpdated; 
public event EventHandler<MtQuoteEventArgs> QuoteUpdate; 
public event EventHandler<MtQuoteEventArgs> QuoteAdded; 
public event EventHandler<MtQuoteEventArgs> QuoteRemoved; 

  • 还有一个小的 VB测试应用看起来像这样:
    • And a small VB Test app look like this:
    • Imports MtApi
      Public Class Form1
          Private apiClient As MtApiClient
          Public Sub New()
              InitializeComponent()
              apiClient = New MtApiClient
              AddHandler apiClient.QuoteUpdated, AddressOf QuoteUpdatedHandler
          End Sub
      
          Sub QuoteUpdatedHandler(sender As Object, symbol As String, bid As Double, ask As Double)
              Dim quoteSrt As String
              quoteSrt = symbol + ": Bid = " + bid.ToString() + "; Ask = " + ask.ToString()
              ListBoxQuotesUpdate.Invoke(Sub()
                                             ListBoxQuotesUpdate.Items.Add(quoteSrt)
                                         End Sub)
              Console.WriteLine(quoteSrt)
          End Sub
          Private Sub btnConnect_Click(sender As System.Object, e As System.EventArgs) Handles btnConnect.Click
              apiClient.BeginConnect(8222)
          End Sub
          Private Sub btnDisconnect_Click(sender As System.Object, e As System.EventArgs) Handles btnDisconnect.Click
              apiClient.BeginDisconnect()
          End Sub
      End Class
      


      更新

      作为参考,我们有以下相关的DLL调用,它们由属性,类型 __ doc __ 提供:

      For reference, we have the following relevant DLL calls, given by the attributes, types and __doc__:

      attr: QuoteAdded             type: <class 'CLR.EventBinding'>    doc: <n/a>
      attr: QuoteRemoved           type: <class 'CLR.EventBinding'>    doc: <n/a>
      attr: QuoteUpdate            type: <class 'CLR.EventBinding'>    doc: <n/a>
      attr: QuoteUpdated           type: <class 'CLR.EventBinding'>    doc: <n/a>
      
      attr: add_QuoteAdded         type: <class 'CLR.MethodBinding'>   doc: Void add_QuoteAdded(System.EventHandler`1[MtApi.MtQuoteEventArgs])
      attr: add_QuoteRemoved       type: <class 'CLR.MethodBinding'>   doc: Void add_QuoteRemoved(System.EventHandler`1[MtApi.MtQuoteEventArgs])
      attr: add_QuoteUpdate        type: <class 'CLR.MethodBinding'>   doc: Void add_QuoteUpdate(System.EventHandler`1[MtApi.MtQuoteEventArgs])
      attr: add_QuoteUpdated       type: <class 'CLR.MethodBinding'>   doc: Void add_QuoteUpdated(MtApi.MtApiQuoteHandler)
      
      attr: remove_QuoteAdded      type: <class 'CLR.MethodBinding'>   doc: Void remove_QuoteAdded(System.EventHandler`1[MtApi.MtQuoteEventArgs])
      attr: remove_QuoteRemoved    type: <class 'CLR.MethodBinding'>   doc: Void remove_QuoteRemoved(System.EventHandler`1[MtApi.MtQuoteEventArgs])
      attr: remove_QuoteUpdate     type: <class 'CLR.MethodBinding'>   doc: Void remove_QuoteUpdate(System.EventHandler`1[MtApi.MtQuoteEventArgs])
      attr: remove_QuoteUpdated    type: <class 'CLR.MethodBinding'>   doc: Void remove_QuoteUpdated(MtApi.MtApiQuoteHandler)
      
      


      类似问题:


      Similar Issues:

      从字面上看,相关的SO问题有100多个,我大概研究了其中的60%以上,但对用例的适用性几乎没有成功.其中一些是:

      There are literally 100's of related SO issue, and I've probably looked at over 60% of them but with nearly zero success to applicability to by use case. Some of which are:

      • Does Python classes support events like other languages?
      • What's the correct way to convert this event handler registration from C# to VB.net?
      • How do I convert a VB delegate into a python event handler?
      • https://ironpython.net/documentation/dotnet/dotnet.html (may also be relevant)
      • https://openbookproject.net/thinkcs/python/english3e/events.html
      • https://code.activestate.com/recipes/410686-c-style-events-in-python/

      推荐答案

      几天和很长时间之后,我发现了一系列错误.与往常一样,将2-3个简单的错误结合在一起会使您的生活长期处于悲惨境地.但是,最大的错误是,愚蠢的以为列表员(又名 delegate )必须要加上一堆 __ init __ __ iadd __ 函数.错误的!Python.NET大部分时间都可以正常工作,但是如果您犯了任何小错误,那么您得到的错误(如果有的话)几乎是没有用的.

      After a few days and some long hours I found a combination of mistake(s). As always, a combination of 2-3 simple mistakes can make your life miserable for a long time. But the biggest mistake of all, was being fooled to think that a listner (aka. delegate) had to be complicated with a bunch of __init__ and __iadd__ functions. Wrong! Python.NET just works most of the time but the errors you get (if any at all) are pretty useless if you make any small mistake.

      我的原始代码有1.5个问题.

      There are 1.5 problems with my original code.

      • 有2种不同的 Quote 函数,即:

      QuoteUpdate ,它返回发件人和一个名为"MtQuoteEventArgs"的对象.在.NET中

      QuoteUpdate which returns sender and an object named "MtQuoteEventArgs" in .NET

      QuoteUpdated 会返回发件人和3个参数.

      因此,我们需要修复 printTick()函数和侦听器行.

      Therefore we need to fix both the printTick() function and the listener line.

      更正后的代码是:

      def printTick(source, symbol, ask, bid):
          print('Tick: Symbol: {}  Ask: {:.5f}  Bid: {:.5f}'.format(symbol, ask, bid))
      
      ...
      
      mtc.QuoteUpdates += printTick
      

      有关C#事件&代表:

      这篇关于如何使用pythonnet在python侦听器中订阅.NET事件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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