Там какой-либо путь состоит в том, чтобы заставить этот сценарий работать?
Существует сценарий Python. Это встроено в DLL путем запущения этого скрипта с IronPython:
import clr
clr.CompileModules("CompiledScript.dll", "script.py")
Цель состоит в том, чтобы назвать методы этого DLL из кода C#. Отражатель.NET показывает, что существует один класс в DLL - DLRCashedCode
и методы, которыми мы интересуемся, являются частными статическими методами этого класса.
Например, в сценарии существует функция:
def scriptMethod(self, text):
...
Его представление в DLL:
private static object scriptMethod(Closure closure1, PythonFunction $function, object self, object text)
{
...
}
Closure
и PythonFunction
классы IronPython (из Microsoft.Scripting.dll и IronPython.dll).
Пока все хорошо. Этот метод действительно ли возможно быть названным кодом C#? Идея использовать отражение как
Type t = typeof(DLRCachedCode);
string methodName = "scriptMethod";
MethodInfo method = t.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Static);
object[] parameters = new object[] { "param1", "param2" }; // the "params problem"
method.Invoke(null, parameters);
кажется более твердым из-за установки параметров метода. Если они (в любом случае) инициализируются правильно, мы могли бы ожидать, что метод будет работать гладко?
Существует ли лучший способ назвать это методами от C#? По всевозможным причинам мы предпочитаем создавать сценарий как блок.NET а не называть сам сценарий.
Вроде того. Вы не можете получить доступ к методам Python непосредственно из кода C#. Если только вы не играете с C# 4.0 и динамическим ключевым словом или вы очень, очень особенный ;). Однако, вы можете скомпилировать класс IronPython в DLL, а затем использовать хостинг IronPython на C# для доступа к методам (это для IronPython 2.6 и .NET 2.0).
Создайте программу на C# вот так:
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);
}
}
}
Сделайте тривиальный класс на Python вот так:
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
Скомпилируйте его (я использую SharpDevelop), но метод clr.CompileModules
также должен работать. Затем запихните скомпилированную MyClass.dll
в каталог, где живет скомпилированная программа на C# и запустите ее. В результате вы должны получить следующее:
Hello World!
I'm in a compiled class (I hope)
in some method
in some method
True
False
Press any key to continue . . .
Это включает в себя более прямое решение Джеффа, которое устраняет необходимость создавать и компилировать небольшой "корешок" на Python, а также показывает, как можно создавать вызовы функций C#, которые обращаются к методам в классе Python.
CLR.CompileModules
- это чисто оптимизация нагрузки - она не делает сценарии напрямую доступными для статического языка, такого как C #. Вам нужно будет провести время выполнения IrryPython, а затем вы можете загрузить DLL во время выполнения и использовать интерфейсы хостинга IronPython для доступа к нему.