Use another language to call a function: Difference between revisions

Content deleted Content added
Begin python solution. Please simplify, if possible.
Line 446: Line 446:


=={{header|Python}}==
=={{header|Python}}==

Our embedded python function a) uses information from the main routine in c, and b) determines the information to populate the result returned to the main routine. This, I believe, fulfills the task requirement. The modifications and compilation are shown for Ubuntu linux Autumn 2011 version, with python3. It's easier to call a dynamic library from python using the ctypes module. Consider using <tt>PyRun_SimpleString</tt> to have main.c call python calling back to c.
<lang python>
# store this in file rc_embed.py
def query(buffer_length):
message = b'Here am I'
L = len(message)
n = min(L,buffer_length)
#print(message[:n])
return bytes(message[:n])
</lang>

main.c
<lang c>
#if 0
//I rewrote the driver according to good sense, my style,
//and discussion --Kernigh 15:45, 12 February 2011 (UTC).
#endif

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main(int argc,char*argv[]) {
char Buffer[1024], *pc;
unsigned Size = sizeof(Buffer);
if (!Query(Buffer,&Size))
fputs("Failed to call Query",stdout);
else
for (pc = Buffer; Size--; ++pc)
putchar(*pc);
putchar('\n');
return EXIT_SUCCESS;
}
</lang>

In Query.c I don't promise to have tested every case with missing module, missing function, or to have used <tt>Py_DECREF</tt> correctly.
<lang c>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<Python.h>

int Query(char*Data,unsigned*Length) {
char *module = "rc_embed", *function = "query";
PyObject *pName, *pModule, *pFunc, *pResult, *pArgs, *pLength;
long result = 0;
if (!Py_IsInitialized())
Py_Initialize();
pName = PyUnicode_FromString(module);
pModule = PyImport_Import(pName);
Py_DECREF(pName);
if (NULL == pModule) {
PyErr_Print();
fprintf(stderr,"Failed to load \"%s\"\n",module);
return 0;
}
pFunc = PyObject_GetAttrString(pModule,function);
if ((NULL == pFunc) || (!PyCallable_Check(pFunc))) {
if (PyErr_Occurred())
PyErr_Print();
fprintf(stderr,"Cannot find function \"%s\"\n",function);
if (NULL != pFunc)
Py_DECREF(pFunc);
Py_DECREF(pModule);
return 0;
}
pArgs = PyTuple_New(1);
pLength = PyLong_FromUnsignedLong((unsigned long)(*Length));
if (NULL == pLength) {
Py_DECREF(pArgs);
Py_DECREF(pFunc);
Py_DECREF(pModule);
return 0;
}
PyTuple_SetItem(pArgs,0,pLength);
pResult = PyObject_CallObject(pFunc, pArgs);
if (NULL == pResult)
result = 0;
else if (!PyBytes_Check(pResult)) {
result = 0;
Py_DECREF(pResult);
} else {
*Length = (unsigned)PyBytes_Size(pResult);
strncpy(Data,PyBytes_AsString(pResult),*Length);
Py_DECREF(pResult);
result = 1;
}
Py_DECREF(pArgs);
Py_DECREF(pFunc);
Py_DECREF(pModule);
Py_Finalize();
return result;
}
</lang>

Compilation, linkage, execution. Note the python tools used to extract the correct flags.
<lang bash>
$ make main.o
cc -c -o main.o main.c
$ D=$( dirname $( which python3 ) )
$ gcc $( $D/python3.2-config --cflags ) -c Query.c
In file included from /usr/include/python3.2mu/Python.h:8:0,
from Q.c:18:
/usr/include/python3.2mu/pyconfig.h:1173:0: warning: "_POSIX_C_SOURCE" redefined [enabled by default]
/usr/include/features.h:214:0: note: this is the location of the previous definition
$ gcc -o main main.o Query.o $( $D/python3.2-config --ldflags )
$ ./main
Here am I
$
</lang>


=={{header|Tcl}}==
=={{header|Tcl}}==