【问题标题】:Handle an event thrown in IronPython from vb.net处理从 vb.net 在 IronPython 中抛出的事件
【发布时间】:2017-07-11 18:32:21
【问题描述】:

我正在使用IronPython 尝试连接到我的 vb.net 程序。

我正在尝试找到一些路径让事件在两者之间传播(不确定这是否可能。)

我所做的是创建一个通用的DLL,我的程序 (vb.net) 引用它以及 IronPython 脚本,然后在我的 vb.net 代码中执行 python。

这可能在IronPython 中吗?我找不到任何方法在它们之间传递 A 类型的对象,或者让它们通过事件链接起来。

【问题讨论】:

    标签: python vb.net dll ironpython


    【解决方案1】:

    处理异常的一般方法要求您的 VB.net 程序应该对 IronPython 程序具有引用/依赖关系。异常被抛出调用堆栈,直到它们被处理。您描述的架构表明它们是对等的并且彼此没有直接依赖关系,因此处理这些异常将无法正常在 Catch 块中工作。

    我能看到这个工作的唯一方法(我的头顶)是如果你可以通过将异常发送到公共 DLL 中的一个方法来处理 IronPython 中的异常,该方法引发一个事件,异常作为事件 args 的一部分比如你可以得到一个UnhandledException 事件

    AddHandler My.Application.UnhandledException, AddressOf Foo
    

    这将允许您的 VB 代码响应 IronPython 应用程序中发生的事情。

    【讨论】:

    • 我昨天在发布活动后试了一下。我无法让事件在我的 .net 代码中触发。据我所知,事件需要属于一个对象,并且不能在 python 和 .net 之间共享一个对象。
    • 不能共享对象是什么意思?当 IronPython 调用返回 .net 对象的方法时,IronPython 现在将引用该对象,就像它是在 .Net 中创建的一样使用。
    【解决方案2】:

    IronPython 广泛使用System.Reflection。它会自动导入对其可用的类型和方法。

    您可以在 DLL 类库中公开您的类型。

    构建 DLL 后,您可以将其导入“IronPython”

    import clr    
    clr.AddReferenceToFileAndPath(r"C:\SomeFolder\SomeClassLibrary.dll")
    

    您还可以动态加载 DLL 和导入命名空间:

    sys.path.append(r"C:\SomeFolder")  
    clr.AddReference ("SomeClassLibrary.dll") # Your Class libary
    import SomeNamspace  # import SomeNamespace from your dll.
    

    在您的库中公开您的事件:

    Public Class SomeClass
    
        Public Event SomeEvent ....
    

    然后您可以在 `IronPython

    中使用它们
    def SomeHandleHandler(*args):
        pass
    
    Foo.SomeEvent += SomeHandleHandler
    

    要执行相反的操作并使用IronPython 触发事件,您只需在您的 Vb.Net 代码中添加处理程序。

    这是工作代码:

    类库 MyClassLibary 中的 MyIpyClass.vb

    Public Class MyIpyClass
        Public Event MyEvent()
    
        Public Sub New()
            AddHandler MyEvent, HandleMyEvent()
        End Sub
    
        Private Function HandleMyEvent() as MyEventEventHandler
            Console.WriteLine("Raised My Event")
            Return Nothing
        End Function
    
    
        Public Sub RaiseMyEvent()
            RaiseEvent MyEvent()
        End Sub
    
    End Class
    

    IronPython 代码:

    import clr
    clr.AddReference("System.Windows.Forms")
    clr.AddReference("System.Drawing")
    clr.AddReferenceToFileAndPath("C:\\MyDllPath\\MyClassLibary.dll")
    import MyClassLibary
    from System.Windows.Forms import *
    from System.Drawing import *
    
    
    def mevent(*args): print("Event From IPY") # create IPython event hander for MyIpyClass.MyEvent
    
    m = MyClassLibary.MyIpyClass() # create new instance of my class
    m.MyEvent += mevent # Add IPythong Handler
    m.RaiseMyEvent() # For Simplicity, Call MyIpyClass.MyEvent.RaiseEvent to raise the event
    
    
    
    f = Form() # Create a Form to handle some events from System.Windows.Forms
    f.Text = "My Form"
    
    #defne a form click handler to print out the event args
    def click(*args): print args
    f.Click += click  
    
    b = Button() # Create a button and add it to the form
    b.Text = "GO"
    b.Name = "GO"
    b.Location = Point(10,10)
    
    #create a button click handler that prints hellow word
    def click(f, a):
        print("hello world")
    
    #assign the button click handler
    b.Click += click
    
    #add the button to the form
    f.Controls.Add(b)
    
    #call Form.ShowDialog() - Show() blocks and will hang the form.
    f.ShowDialog()
    

    【讨论】:

    • 我自己做到了这一点。我不能做的是让 python 抛出事件并在我的 VB.net 代码中处理。
    • 对不起,我应该要求您澄清您的问题。如果你做到了那一步,那么剩下要做的就是像在 VB 中一样使用你的对象。我附上了完整的工作代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-25
    • 1970-01-01
    • 2014-05-22
    • 1970-01-01
    • 1970-01-01
    • 2020-01-16
    相关资源
    最近更新 更多