Dear all,
Currently, I am facing an issue to do scripting with a managed object in
python engine.
I managed to import the module and set an attribute value to the managed
object.
The issue is in the next step where I am trying to use the module in a
statement/expression via PythonEngine.RunString or RunSimpleString method.
As far as I know:
- RunString() is not working because it always return null value. I tried
running a simple expression, e.g., "1 + 1", and it returned null value. I
believe the fix
here<http://osdir.com/ml/python.dotnet/2007-03/msg00009.html> could
solve this bug (if it really is...)
- RunSimpleString() executes expression from the __main__ module
implicitly. I have not found any possible way yet to include the module I've
imported in the beginning into __main__ module.
So...
I made a little modification on the code by creating a new class that
represents the Python Module object.
This is how I use the modification in my code.
> PythonEngine.Initialize();
// create __main__ and my own module
PyModule __main__ = new
> PyModule(PythonEngine.ImportModule("__main__"));
PyModule birdwrapper = new
> PyModule(PythonEngine.ImportModule("birdwrapper"));
> // set the value of the attribute to a managed object
birdwrapper.SetAttr("pet", PyObject.FromManagedObject(new
> Eagle("Foo")));
> // include my own module in the __main__ module
__main__.AddObject("birdwrapper", birdwrapper);
> // run the script from this method because it is called from
> the __main__ module
PythonEngine.RunSimpleString("birdwrapper.Fly()");
> PythonEngine.Shutdown();
++ in runtime.cs:
> internal static bool PyModule_Check(IntPtr ob)
{
return PyObject_TYPE(ob) == Runtime.PyModuleType;
}
[DllImport(Runtime.dll, CallingConvention = CallingConvention.Cdecl,
ExactSpelling = true, CharSet = CharSet.Ansi)]
internal unsafe static extern int
PyModule_AddObject(IntPtr module, string name, IntPtr value);
pymodule.cs:
> public class PyModule : PyObject
{
> public PyModule(IntPtr ptr) : base(ptr) { }
> public PyModule(PyObject o) : base()
{
if (!IsModuleType(o))
{
throw new ArgumentException("object is not a module");
}
Runtime.Incref(o.obj);
obj = o.obj;
}
> public PyModule(string name) : base()
{
obj = Runtime.PyModule_New(name);
if (obj == IntPtr.Zero)
{
throw new PythonException();
}
}
> public static bool IsModuleType(PyObject value)
{
return Runtime.PyModule_Check(value.obj);
}
> public void AddObject(string name, PyObject value)
{
int op = Runtime.PyModule_AddObject(obj, name, value.obj);
if (op != 0)
throw new PythonException();
}
> }
I hope the code could illustrate what I am basically trying to achieve with
python.net.
I wonder if there is a possible way to do this without modifying the code.
Could anyone please advise?
--
Best regards,
Fedry Kemilau