Build Python scripts and call methods from C#

后端 未结 2 741
南笙
南笙 2020-12-24 09:10

Is there any way to make this scenario work?

There is a Python script. It is built into a DLL by running this script with IronPython:

import clr
clr.         


        
相关标签:
2条回答
  • 2020-12-24 09:55

    Sort of. You cannot access the Python methods directly from C# code. Unless you are playing with C# 4.0 and the dynamic keyword or you are very, very special ;). However, you can compile an IronPython class to a DLL and then use IronPython hosting in C# to access the methods (this is for IronPython 2.6 and .NET 2.0).

    Create a C# program like this:

    using System;
    using System.IO;
    using System.Reflection;
    using IronPython.Hosting;
    using Microsoft.Scripting.Hosting;
    // we get access to Action and Func on .Net 2.0 through Microsoft.Scripting.Utils
    using Microsoft.Scripting.Utils;
    
    
    namespace TestCallIronPython
    {
        class Program
        {
            public static void Main(string[] args)
            {
                Console.WriteLine("Hello World!");
                ScriptEngine pyEngine = Python.CreateEngine();
    
                Assembly myclass = Assembly.LoadFile(Path.GetFullPath("MyClass.dll"));
                pyEngine.Runtime.LoadAssembly(myclass);
                ScriptScope pyScope = pyEngine.Runtime.ImportModule("MyClass");
    
                // Get the Python Class
                object MyClass = pyEngine.Operations.Invoke(pyScope.GetVariable("MyClass"));
    
                // Invoke a method of the class
                pyEngine.Operations.InvokeMember(MyClass, "somemethod", new object[0]);
    
                // create a callable function to 'somemethod'
                Action SomeMethod2 = pyEngine.Operations.GetMember<Action>(MyClass, "somemethod");
                SomeMethod2();
    
                // create a callable function to 'isodd'
                Func<int, bool> IsOdd = pyEngine.Operations.GetMember<Func<int, bool>>(MyClass, "isodd");
                Console.WriteLine(IsOdd(1).ToString());
                Console.WriteLine(IsOdd(2).ToString());
    
                Console.Write("Press any key to continue . . . ");
                Console.ReadKey(true);
            }
        }
    }
    

    Make a trivial Python class like this:

    class MyClass:
        def __init__(self):
            print "I'm in a compiled class (I hope)"
    
        def somemethod(self):
            print "in some method"
    
        def isodd(self, n):
            return 1 == n % 2
    

    Compile it (I use SharpDevelop) but the clr.CompileModules method should also work. Then shove the compiled MyClass.dll into the directory where the compiled C# program lives and run it. You should get this as the result:

    Hello World!
    I'm in a compiled class (I hope)
    in some method
    in some method
    True
    False
    Press any key to continue . . .
    

    This incorporates Jeff's more direct solution that eliminates having to create and compile a small Python 'stub' and also shows how you can create C# function calls that access the methods in the Python class.

    0 讨论(0)
  • 2020-12-24 10:05

    The clr.CompileModules is purely a load-time optimization - it doesn't make the scripts directly available to a static languge like C#. You'll need to host the IronPython runtime, and then you can load the DLL into the runtime and use IronPython's hosting interfaces to access it.

    0 讨论(0)
提交回复
热议问题