How do I inject C# object to Python code?

Hi,

I have been using Python.net to run a Python script from a C# WPF app. C# code injects necessary C# objects by using “PyScope.Set(variable name, object.ToPython)()” like so:

const string Script = "import matplotlibtest\n"
                      + "matplotlibtest.matplotlib_test(var1, var2)\n";
dynamic scope = Py.CreateScope();
scope.Set("var1", (new Range(2)).ToPython());
scope.Set("var2", 0.01.ToPython());
scope.Exec(Script);

In the above example, the Python script requires two C# objects that have already been instantiated in C#.

How do I do the same thing with Alternet with CPython scriptor?

Thanks,

Hi,

Please use a code like to the following:

scriptRun.GlobalItems.Add(new ScriptGlobalItem("var1", myDotNetObject));

You can find a full working example of this in the ObjectRefence quick start you can find in <your-alternet-studio-installation-location>\Demo\Scripter.Python\QuickStarts\ObjectReference

Hi Yevgeni,

I was able to register objects. My next question is how to register C# enums and types? For example, they can be used as parameters of Python functions.

Thanks for your help.

For that will need to reference an assembly with those types and import the required namespace. For example:

            scriptRun.ScriptSource.References.Add("MyTypes.dll");
            scriptRun.ScriptSource.Imports.Add("My.Name.Space");

Hi Yevgeni,

That worked. Great!

I have one more question (hopefully the final one). I got an exception message box, saying “TypeError. No method matches given arguments for MyMethod: (<class ‘list’>)”, when I ran my Python script that calls a C# object method that has a List parameter as shown below:

public void MyMethod(List<SomeClass> list) {...}

The list that is passed to the C# method is created in Python just like usual - i.e, list = [].

Adding the following code did not help either:

scriptRun.ScriptSource.Imports.Add("System"); scriptRun.ScriptSource.Imports.Add("System.Collections.Generic");

Any idea?

Hi,

This is the Python code you can use when passing List<> as an argument to a method defined like public void MyMethod(List<int> list)

  l = System.Collections.Generic.List[int]()
  l.Add(1)
  l.Add(2)
  l.Add(3)

  obj.MyMethod(l)

However, if you would like to pass a Python-style list like

obj.MyMethod([1, 2, 3])

just use a C# array type in an argument:

public void MyMethod(int[] list).

Hi yevgeni,

That worked!

Thanks a lot.

Hi Yevgeni,

I’m back again. I verified that the following code worked with the embedded Python:

scriptRun.GlobalItems.Add(new ScriptGlobalItem("api", new Api()));
...
    public class Api
    {
        public void Run()
        {
            var x = 0;
        }
    }

However, it doesn’t seem to work with the fully installed Python (DAP?). It appears to be a namespace issue…

I modified the project you sent - Microsoft OneDrive - Access files anywhere. Create docs with free Office Online.

Could you test that on your end?

Thanks!

Hi,

DAP Debugging works for a regular scripts executed as separate processes by running python.exe. If you would like to embed python in your application and link C# application objects to it, you can use AlterNET Scripter/Debugger for Python. For a complete debugging example, you can refer to a demo project which is installed by default to “C:\Users\Public\Documents\AlterNET Software\AlterNET Studio v.8\Demo\Scripter.Python.Wpf\QuickStarts\Debugger\DebuggerIntegration” directory.

If you would like to embed python in your application and link C# application objects to it,

That depends. If the user could install their desired python packages in the embedded folder, the answer is yes. How would the user do that?

Otherwise, no. I would like the user to install desired Python and its packages, as long as the Pythonnet.dll that is integrated into the Alternet Studio supports that specific version of Python.

The “DebuggerIntegration” sample you referred to uses embedded Python. I have already verified that referencing C# objects worked fine there.

Would you be able to create another sample “DebuggerIntegrationFullPythonWithObjectReference”?

Thanks for your help!

Hello,

You can change SetupPython() method in the Form1.cs file of the DebuggerIntegration sample be similar to following:


        private void SetupPython()
        {
            CodeEnvironment.PythonPath = @"path/to/python";
            return;
        }

Then the python distribution specified will be used.