void ScriptHost::Run(System::String *filename, System::String *function,int argc,System::String *args[]) {
Py_Initialize();
PyObject *pName, *pModule, *pDict, *pFunc;
PyObject *pArgs, *pValue;
char* fName = (char*)(Marshal::StringToHGlobalAnsi(filename).ToPointer());
System::Console::Out->Write("Contents of fName: ");
System::Console::Out->WriteLine(fName);
pName = PyString_FromString(fName);
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (pModule != NULL) {
pDict = PyModule_GetDict(pModule);
pFunc = PyDict_GetItemString(pDict,(char*)Marshal::StringToHGlobalAnsi(function).ToPointer());
if (pFunc && PyCallable_Check(pFunc)) {
pArgs = PyTuple_New(argc);
for (int i = 0; i < argc; ++i) {
pValue = PyInt_FromLong(Convert::ToInt32(args[i]));
if (!pValue) {
Py_DECREF(pArgs);
Py_DECREF(pModule);
Console::Error->WriteLine("Cannot convert argument");
return;
}
/* pValue reference stolen here: */
PyTuple_SetItem(pArgs, i, pValue);
}
pValue = PyObject_CallObject(pFunc, pArgs);
Py_DECREF(pArgs);
if (pValue != NULL) {
System::Console::Out->WriteLine("Result of call: {0}",Convert::ToString(PyInt_AsLong(pValue)));
Py_DECREF(pValue);
}
else {
Py_DECREF(pModule);
PyErr_Print();
System::Console::Error->WriteLine("Call failed");
return;
}
/* pDict and pFunc are borrowed and must not be Py_DECREF-ed */
}
else {
if (PyErr_Occurred())
PyErr_Print();
Console::Error->WriteLine("Cannot find function \"{0}\"", function);
}
Py_DECREF(pModule);
}
else {
PyErr_Print();
Console::Error->WriteLine("Failed to load \"{0}\"\n", filename);
return;
}
Py_Finalize();
return;
}
And the output is:
Contents of fName: test.py
ImportError: No module named py
Failed to load "test.py"
Any help would be most appreciated.
🔒 Locked
Python doesn't like me
Advertisement
Original Post
Ok, so... I''m 99% sure the problem isn''t the string marshalling now. It seems that Python doesn''t particularly like me or how I''m interfacing with it. I made some adjustements and I now have the following code:
You need to load it like
The .py on the latter makes Python think that your test module is a directory, and that py is a module in that directory (i.e. it thinks there's a test/py.py, test/py.pyc or test/py.pyd file)
[edit]Just realized that you do this in C, rather than in Python. So you need fName to be the base, rather than the base+extension.
[edited by - Flarelocke on April 28, 2004 10:17:25 PM]
import testinstead of
import test.py
The .py on the latter makes Python think that your test module is a directory, and that py is a module in that directory (i.e. it thinks there's a test/py.py, test/py.pyc or test/py.pyd file)
[edit]Just realized that you do this in C, rather than in Python. So you need fName to be the base, rather than the base+extension.
[edited by - Flarelocke on April 28, 2004 10:17:25 PM]
I think it is much cleaner to run the code from a string.
All you need to do is construct the string.
Of course, if you want the content of the return value, it is easier by directly calling the C api.
[edited by - Gorg on April 28, 2004 10:46:36 PM]
[edited by - Gorg on April 28, 2004 10:47:05 PM]
void ExecuteCode( const std::string& code )
{
int result = PyRun_SimpleString( const_cast<char*>(code.c_str()));
if ( result == -1 )
{
throw std::runtime_error( std::string( "Python : Error running code : " ) + code );
}
}
ExecuteCode( "import module\nmodule.func( arg1, arg2)" )
All you need to do is construct the string.
Of course, if you want the content of the return value, it is easier by directly calling the C api.
[edited by - Gorg on April 28, 2004 10:46:36 PM]
[edited by - Gorg on April 28, 2004 10:47:05 PM]
quote:
Original post by Flarelocke
...
Just realized that you do this in C, rather than in Python. So you need fName to be the base, rather than the base+extension.
...
I passed it in "test" instead of "test.py" and the new result was:
Contents of fName: test
Cannot find function "multiply"
The source for my python file is:
def multiply(a,b):
print "Will compute", a, "times", b
c = 0
for i in range(0, a):
c = c + b
return c
Try test.multiply rather than just multiply?
Can you try to make a simplified test cast? i.e. substitute values in for these arguments, remove some of the extra lines, etc.
@AP- No, it hates me.
@Flare-
Ok, so, here''s the minimal source:
Result is: "pFunc is null." I have no idea what that means is wrong. The Python/C API isn''t very well documented.
@Flare-
Ok, so, here''s the minimal source:
void ScriptHost::Run() {
Py_Initialize();
PyObject *pName, *pModule, *pDict, *pFunc;
pName = PyString_FromString("test");
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (pModule != NULL) {
pDict = PyModule_GetDict(pModule);
pFunc = PyDict_GetItemString(pDict,"multiply");
if (pFunc == NULL) {
Console::Out->WriteLine("pFunc is null.");
return;
}
else if (!PyCallable_Check(pFunc)) {
Console::Out->WriteLine("Function not callable");
return;
}
else {
System::Console::Out->WriteLine("pFunc not null and function callable.");
return;
}
}
else {
PyErr_Print();
Console::Out->WriteLine("Could not find module.");
return;
}
Py_Finalize();
return;
}
Result is: "pFunc is null." I have no idea what that means is wrong. The Python/C API isn''t very well documented.
It was my pleasure.
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement