Hi,
There is a problem in the current $CRYSTAL/plugins/cscript/cspython, in that
the csPython::Call functions have no implementation. Naturally I want to fill
out these functions, but it would make and break the current iScript object.
Not to be bullish, but
bool csPython::LoadModule(const char* name)
{
csString s;
s << "import " << name;
return RunText(s);
}
is bad, since the only way I can explicitly load python files
(i.e ./data/custom.py), is to modify PYTHONPATH (which CS doesn't have a
function for as far as I'm aware and is platform dependent), then import that
module.
Take this code (minus the error checking and INC/DECREF's for clarity)
-- amir.py --
def foo(a, b):
return a * b
-- main.cpp --
#include <iostream>
#include <Python.h>
int main()
{
Py_Initialize();
/*PyObject* pyIntObject = PyInt_FromLong(5);
if (pyIntObject == NULL) ; // Error
Py_DECREF(pyIntObject);
PyRun_SimpleString("print 'hello'");*/
// open file and load module
FILE *file = fopen("amir.py", "r");
PyRun_SimpleFile(file, "amir.py");
// get main module
PyObject *main_module = PyImport_AddModule("__main__");
PyObject *global_dict = PyModule_GetDict(main_module);
// get function from global namespace
/*! this bit I'm unsure of... can I load the function, explicitly
from the loaded file? I remember being able to do so, but can't
find out how... */
PyObject *foo = PyDict_GetItemString(global_dict, "foo");;
PyObject *arg1 = PyInt_FromLong(2), *arg2 = PyInt_FromLong(8);
// make tuple of arguments
PyObject *args = PyTuple_New(2);
PyTuple_SetItem(args, 0, arg1);
PyTuple_SetItem(args, 1, arg2);
// call function and get return object
PyObject *ret = PyObject_CallObject(foo, args);
int result = PyInt_AsLong(ret);
std::cout << result << "!\n";
Py_Finalize();
return 0;
}
There are 2 changes that would be made here
1) csPython::LoadModule(..) would load absolute paths as opposed to pythonic
module style
is->LoadModule("x.k") becomes is->LoadModule("../some/path/maybe/vfs/x/k.py")
2) the csPython::Call functions get implemented.
I've already modified cspython and the pysimp to get a working prototype
int result = 0;
is->Call("foo", result, "");
printf("result : [%i]\n",result);
The problem here is that functions exist in the global namespace :S, each
function must have a unique identifier.
Here is another alternative which I haven't yet tried. (better from a python
POV, but maybe not the best for CS)
#include <Python.h>
int main()
{
char *cstrret;
Py_Initialize();
PyObject *module = PyImport_ImportModule("amir");
PyObject *foo = PyObject_GetAttrString(mymod, "foo");
PyObject *args = ...; // build value or whatever
PyObject *ret = PyEval_CallObject(foo, args);
Py_Finalize();
return 0;
}
This is a different approach, which I would prefer where it not for the
structural changes it would bring to iScript. For a start the module
references would have to be stored somehow (hash map or iScriptModule?), and
then the functions called by doing
iscript->FindLoadedModule("amir")->Call("foo", &i, 2, 8);
Preferrably if it is possible to mix first one (so can load python files from
VFS paths) and second one (being explicit about which function the module is
called from)- it should be, but I can't remember/find out how.
What do you all think?
-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems? Stop! Download the new AJAX search engine that makes
searching your log files as easy as surfing the web. DOWNLOAD SPLUNK!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=103432&bid=230486&dat=121642
_______________________________________________
Crystal-main mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/crystal-main
Unsubscribe: mailto:[EMAIL PROTECTED]