I'm trying to use an embedded python interpreter from C# using pythonnet (the python3 compatible version found at https://github.com/renshawbay/pythonnet)
My interpreter is located in D:\src\scratch\TestPythonNet\TestPythonNet\PythonRuntime and has the "Lib" and "Libs" folder from the python distribution.
I've tested using the following code:
<!-- language: c# -->
PythonEngine.PythonHome = #"D:\src\scratch\TestPythonNet\TestPythonNet\PythonRuntime";
PythonEngine.ProgramName = "PythonRuntime";
PythonEngine.Initialize();
using (Py.GIL())
{
PythonEngine.RunSimpleString("print(1)");
}
But, it doesn't work. I get a "SystemError: PyEvalCodeEx: NULL globals". Everytime I try to get an object from python, the code fails.
What am I doing wrong?
I think I've found the answer. If I add a reference to the "clr" module provided by pythonnet, it does work
PythonEngine.PythonHome = #"D:\src\scratch\TestPythonNet\TestPythonNet\PythonRuntime";
PythonEngine.ProgramName = "PythonRuntime";
PythonEngine.Initialize();
// ==>
PyObject a = PythonEngine.ImportModule("clr");
using (Py.GIL())
{
PythonEngine.RunSimpleString("print(1)");
}
Related
My problem is that I'm trying to use Python.NET inside Visual Studio, I installed Python 3.5, and the python.NET package trough nuget and trough pip too.
added namespace Python.Runtime in my Form application, and the Python.Runtime.dll is there in the references too.
I tried to use a sample code from the offical site: offical site
using Python.Runtime;
// create a person object
Person person = new Person("John", "Smith");
// acquire the GIL before using the Python interpreter
using (Py.GIL())
{
// create a Python scope
using (PyScope scope = Py.CreateScope())
{
// convert the Person object to a PyObject
PyObject pyPerson = person.ToPython();
// create a Python variable "person"
scope.Set("person", pyPerson);
// the person object may now be used in Python
string code = "fullName = person.FirstName + ' ' + person.LastName";
scope.Exec(code);
}
}
The Py.GIL() part works and I already tried to import numpy package and do some basic calculations with it, it worked well.
However the PyScope is just not recognized, nor do Py.CreateScope.
("The type or namespace PyScope could not be found")
Tried to write Python.Runtime.PyScope, tried reinstalling, tried older package, used console app and winforms app too, however nothing seems to work.
Am I missing something here?
I ran into this problem too. Using var instead of PyScope worked for me. As in:
using (var scope = Py.CreateScope())
Edit & Alternative: when I visited the definition of CreateScope(), the output type was PyModule:
public static PyModule CreateScope();
public static PyModule CreateScope(string name);
Using this instead of var also works for me:
using (PyModule scope = Py.CreateScope())
If that doesn't work for you, visiting the definition of the function and using the output type listed in your version likely will.
The var isn't picky though.
i've got a third party c# dll which has been created in dot net 4.5 and has a platform target of x86. I would like to import this into a python script and I've started off with Rob Deary's answer here. However I can't get his example to work. I'm using python version 2.7.6 and I get an AttributeError as shown below.
File "C:\Python27\Lib\ctypes\__init__.py", line 378, in __getattr__
func = self.__getitem__(name)
File "C:\Python27\Lib\ctypes\__init__.py", line 383, in __getitem__
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'add' not found
Please note that I am aware of Ironpython and Python for dot net but I need to get this working specifically with C python. Here's my sample code which generates the custom c# library: ClassLibrary1.dll
using System;
using System.Runtime.InteropServices;
using RGiesecke.DllExport;
class Test
{
[DllExport("add", CallingConvention = CallingConvention.Cdecl)]
public static int TestExport(int a, int b)
{
return a + b;
}
}
And here's the python script that generates the error
import ctypes
lib = ctypes.cdll.LoadLibrary('ClassLibrary1.dll')
lib.add(3,5)
When I use the line below, this is the output i get. So at least I know that it is loading the dll, but i'm not sure why the function can't be found.
>>> lib.__dict__
{'_FuncPtr': <class 'ctypes._FuncPtr'>, '_handle': 254476288, '_name': 'ClassLibrary1.dll'}
>>>
Any help will be appreciated. Thanks
As the RGiesecke.DllExport documentation states, you need to target a specific architecture (x86 or x64) when building your code. Leaving it set to Any CPU (the default) will not work.
I am trying to create a Solution from a single source file and tested different solutions.
One of them is the following:
var info = ProjectInfo.Create(
projectId,
version: VersionStamp.Default,
name: "TestProject",
assemblyName: "TestProject.dll",
language: LanguageNames.CSharp);
using (var ws = new CustomWorkspace())
{
var project = ws.AddProject(info);
}
But when running this code, I just get an exception saying that "language is not supported".
Any hint about what is happening?
You need to make sure Microsoft.CodeAnalysis.Workspaces.CSharp.dll is copied alongside your project. We detect that it's there and load it to provide C# support.
I'm looking to replicate the following in IronPython and searching has so far been fruitless and/or disappointing.
namespace Groceries
{
public class ChocolateMilk : Milk
{
// Other stuff here
}
}
The idea would be that the compiled Python DLL will be loaded into a C# program through System.Reflection.Assembly.Load and a GetType("Groceries.ChocolateMilk") on the loaded DLL would not return null.
The most recent answer I was able to find was in 2008 and said that it was impossible without using the Hosting API - http://lists.ironpython.com/pipermail/users-ironpython.com/2008-October/008684.html.
Any suggestions on how to accomplish this would be greatly appreciated. Any conclusions that this is currently impossible to do via IronPython will also be appreciated, but less so.
I'm a bit confused on what you're asking here. Are you trying to instantiate that C# code in your IronPython modules? Or do you have the equivalent classes written in IronPython and you want to instantiate them in your C# code?
Based on the link you posted, I suppose you're going for the latter and have IronPython classes that you want instantiated in your C# code. The answer is, you cannot directly instantiate them. When you compile IronPython code to an assembly, you cannot use the types defined there with your regular .NET code since there is not a one-to-one mapping between IronPython classes and .NET classes. You would have to host the assembly in your C# project and instantiate it that way.
Consider this module, Groceries.py compiled to Groceries.dll residing in the working directory:
class Milk(object):
def __repr__(self):
return 'Milk()'
class ChocolateMilk(Milk):
def __repr__(self):
return 'ChocolateMilk()'
To host the module in your C# code:
using System;
using IronPython.Hosting;
using System.IO;
using System.Reflection;
class Program
{
static void Main(string[] args)
{
var engine = Python.CreateEngine();
var groceriesPath = Path.GetFullPath(#"Groceries.dll");
var groceriesAsm = Assembly.LoadFile(groceriesPath);
engine.Runtime.LoadAssembly(groceriesAsm);
dynamic groceries = engine.ImportModule("Groceries");
dynamic milk = groceries.ChocolateMilk();
Console.WriteLine(milk.__repr__()); // "ChocolateMilk()"
}
}
Otherwise to go the other way and create an instance of your .NET type in your IronPython code (as your title suggests). You'd need to add the path to your assembly, reference it, then you could instantiate it as needed.
# add to path
import sys
sys.path.append(r'C:\path\to\assembly\dir')
# reference the assembly
import clr
clr.AddReferenceToFile(r'Groceries.dll')
from Groceries import *
chocolate = ChocolateMilk()
print(chocolate)
I'm using Visual Studio 2010. I have an IronPython console project and a C# console project. This IronPython script works fine when I run it by itself:
import nltk
def Simple():
baconIpsumFile = open('baconipsum.txt', 'r')
baconIpsumCorpus = baconIpsumFile.read()
tokens = nltk.word_tokenize(baconIpsumCorpus)
text = nltk.Text(tokens)
print text
Here is the C# console program, which does not work fine:
using IronPython.Hosting;
namespace IronNLTK.CSharp.Console
{
class Program
{
static void Main(string[] args)
{
var ipy = Python.CreateRuntime();
dynamic test = ipy.UseFile("C:\\Path\\To\\Program.py");
test.Simple();
}
}
}
I get an ImportException: No module named nltk. What am I missing?
sounds like you need to update sys.path to point to wherever NLTK lives.
check this out: Importing external module in IronPython
Awesome news, Visual Studio 2017 is embedded with Anaconda’s Python distribution which has NTLK and other machine learning packages.