all tasks
This commit is contained in:
parent
b83f433714
commit
68f8f3e56b
14735 changed files with 178959 additions and 0 deletions
23
Task/Use-another-language-to-call-a-function/0DESCRIPTION
Normal file
23
Task/Use-another-language-to-call-a-function/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{{clarified-review}}
|
||||
This task is inverse to the task [[Call foreign language function]]. Consider the following [[C]] program:
|
||||
<lang c>#include <stdio.h>
|
||||
|
||||
extern int Query (char * Data, size_t * Length);
|
||||
|
||||
int main (int argc, char * argv [])
|
||||
{
|
||||
char Buffer [1024];
|
||||
size_t Size = sizeof (Buffer);
|
||||
|
||||
if (0 == Query (Buffer, &Size))
|
||||
{
|
||||
printf ("failed to call Query\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
char * Ptr = Buffer;
|
||||
while (Size-- > 0) putchar (*Ptr++);
|
||||
putchar ('\n');
|
||||
}
|
||||
}</lang>
|
||||
Write an implementation of Query in your language and make ''main'' calling it. The function Query takes the buffer a places the string ''Here am I'' into it. The buffer size in bytes is specified by the parameter Length. When there is no room in the buffer, Query shall return 0. Otherwise it overwrites the beginning of Buffer, sets the number of overwritten bytes into Length and returns 1.
|
||||
2
Task/Use-another-language-to-call-a-function/1META.yaml
Normal file
2
Task/Use-another-language-to-call-a-function/1META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
note: Programming environment operations
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
with Interfaces.C; use Interfaces.C;
|
||||
with Interfaces.C.Strings; use Interfaces.C.Strings;
|
||||
|
||||
package Exported is
|
||||
function Query (Data : chars_ptr; Size : access size_t)
|
||||
return int;
|
||||
pragma Export (C, Query, "Query");
|
||||
end Exported;
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package body Exported is
|
||||
function Query (Data : chars_ptr; Size : access size_t)
|
||||
return int is
|
||||
Result : char_array := "Here am I";
|
||||
begin
|
||||
if Size.all < Result'Length then
|
||||
return 0;
|
||||
else
|
||||
Update (Data, 0, Result);
|
||||
Size.all := Result'Length;
|
||||
return 1;
|
||||
end if;
|
||||
end Query;
|
||||
end Exported;
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
gcc -c main.c
|
||||
gnatmake -c exported.adb
|
||||
gnatbind -n exported.ali
|
||||
gnatlink exported.ali main.o -o main
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
; Example: The following is a working script that displays a summary of all top-level windows.
|
||||
|
||||
; For performance and memory conservation, call RegisterCallback() only once for a given callback:
|
||||
if not EnumAddress ; Fast-mode is okay because it will be called only from this thread:
|
||||
EnumAddress := RegisterCallback("EnumWindowsProc", "Fast")
|
||||
|
||||
DetectHiddenWindows On ; Due to fast-mode, this setting will go into effect for the callback too.
|
||||
|
||||
; Pass control to EnumWindows(), which calls the callback repeatedly:
|
||||
DllCall("EnumWindows", UInt, EnumAddress, UInt, 0)
|
||||
MsgBox %Output% ; Display the information accumulated by the callback.
|
||||
|
||||
EnumWindowsProc(hwnd, lParam)
|
||||
{
|
||||
global Output
|
||||
WinGetTitle, title, ahk_id %hwnd%
|
||||
WinGetClass, class, ahk_id %hwnd%
|
||||
if title
|
||||
Output .= "HWND: " . hwnd . "`tTitle: " . title . "`tClass: " . class . "`n"
|
||||
return true ; Tell EnumWindows() to continue until all windows have been enumerated.
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
#if 0
|
||||
I rewrote the driver according to good sense, my style,
|
||||
and discussion.
|
||||
|
||||
This is file main.c on Autumn 2011 ubuntu linux release.
|
||||
The emacs compile command output:
|
||||
|
||||
-*- mode: compilation; default-directory: "/tmp/" -*-
|
||||
Compilation started at Mon Mar 12 20:25:27
|
||||
|
||||
make -k CFLAGS=-Wall main.o
|
||||
cc -Wall -c -o main.o main.c
|
||||
|
||||
Compilation finished at Mon Mar 12 20:25:27
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
extern int Query(char *Data, unsigned *Length);
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
#if 0
|
||||
This is file query.c
|
||||
|
||||
-*- mode: compilation; default-directory: "/tmp/" -*-
|
||||
Compilation started at Mon Mar 12 20:36:25
|
||||
|
||||
make -k CFLAGS=-Wall query.o
|
||||
cc -Wall -c -o query.o query.c
|
||||
|
||||
Compilation finished at Mon Mar 12 20:36:26
|
||||
#endif
|
||||
|
||||
#include<string.h>
|
||||
|
||||
int Query(char *Data, unsigned *Length) {
|
||||
const char *message = "Here am I";
|
||||
unsigned n = strlen(message);
|
||||
if (n <= *Length)
|
||||
return strncpy(Data, message, (size_t)n), *Length = n, 1;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
$ gcc main.c query.o -o main && ./main
|
||||
Here am I
|
||||
$
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
function Query(Buffer: PChar; var Size: Int64): LongBool;
|
||||
const
|
||||
Text = 'Hello World!';
|
||||
begin
|
||||
If not Assigned(Buffer) Then
|
||||
begin
|
||||
Size := 0;
|
||||
Result := False;
|
||||
Exit;
|
||||
end;
|
||||
If Size < Length(Text) Then
|
||||
begin
|
||||
Size := 0;
|
||||
Result := False;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Size := Length(Text);
|
||||
Move(Text[1], Buffer^, Size);
|
||||
Result := True;
|
||||
end;
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
#include <stdio.h>
|
||||
#include "_cgo_export.h"
|
||||
|
||||
void Run()
|
||||
{
|
||||
char Buffer [1024];
|
||||
size_t Size = sizeof (Buffer);
|
||||
|
||||
if (0 == Query (Buffer, &Size))
|
||||
...
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package main
|
||||
|
||||
// #include <stdlib.h>
|
||||
// extern void Run();
|
||||
import "C"
|
||||
import "unsafe"
|
||||
|
||||
func main() {
|
||||
C.Run()
|
||||
}
|
||||
|
||||
const msg = "Here am I"
|
||||
|
||||
//export Query
|
||||
func Query(cbuf *C.char, csiz *C.size_t) C.int {
|
||||
if int(*csiz) <= len(msg) {
|
||||
return 0
|
||||
}
|
||||
pbuf := uintptr(unsafe.Pointer(cbuf))
|
||||
for i := 0; i < len(msg); i++ {
|
||||
*((*byte)(unsafe.Pointer(pbuf))) = msg[i]
|
||||
pbuf++
|
||||
}
|
||||
*((*byte)(unsafe.Pointer(pbuf))) = 0
|
||||
*csiz = C.size_t(len(msg) + 1)
|
||||
return 1
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
#ifdef __GLASGOW_HASKELL__
|
||||
#include "Called_stub.h"
|
||||
extern void __stginit_Called(void);
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <HsFFI.h>
|
||||
|
||||
int main (int argc, char * argv [])
|
||||
{
|
||||
char Buffer [1024];
|
||||
size_t Size = sizeof (Buffer);
|
||||
|
||||
hs_init(&argc, &argv);
|
||||
#ifdef __GLASGOW_HASKELL__
|
||||
hs_add_root(__stginit_Called);
|
||||
#endif
|
||||
|
||||
if (0 == query_hs (Buffer, &Size))
|
||||
{
|
||||
printf ("failed to call Query\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
char * Ptr = Buffer;
|
||||
while (Size-- > 0) putchar (*Ptr++);
|
||||
putchar ('\n');
|
||||
}
|
||||
|
||||
hs_exit();
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
{-# LANGUAGE ForeignFunctionInterface #-}
|
||||
|
||||
module Called where
|
||||
|
||||
import Foreign
|
||||
import Foreign.C.String (CString, withCStringLen)
|
||||
import Foreign.C.Types
|
||||
|
||||
-- place a string into the buffer pointed to by ptrBuff (with size
|
||||
-- pointed to by ptrSize). If successful, sets number of overwritten
|
||||
-- bytes in ptrSize and returns 1, otherwise, it does nothing and
|
||||
-- returns 0
|
||||
query_hs :: CString -> Ptr CSize -> IO CInt
|
||||
query_hs ptrBuff ptrSize = withCStringLen "Here I am"
|
||||
(\(str, len) -> do
|
||||
buffSize <- peek ptrSize
|
||||
if sizeOf str > (fromIntegral buffSize)
|
||||
then do
|
||||
poke ptrSize 0
|
||||
return 0
|
||||
else do
|
||||
poke ptrSize (fromIntegral len)
|
||||
copyArray ptrBuff str len
|
||||
return 1)
|
||||
|
||||
foreign export ccall query_hs :: CString -> Ptr CSize -> IO CInt
|
||||
|
|
@ -0,0 +1 @@
|
|||
ghc -c -O Called.hs
|
||||
|
|
@ -0,0 +1 @@
|
|||
ghc -optc-O calling.c Called.o Called_stub.o -o calling
|
||||
|
|
@ -0,0 +1 @@
|
|||
untyped __call__("functionName", args);
|
||||
|
|
@ -0,0 +1 @@
|
|||
query=:3 :'0&#^:(y < #)''Here am I'''
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
#include<stdio.h>
|
||||
#include<stdlib.h>
|
||||
#include<string.h>
|
||||
|
||||
int Query(char*,unsigned*);
|
||||
|
||||
int main(int argc,char*argv[]) {
|
||||
char Buffer[1024], *pc;
|
||||
unsigned Size = (unsigned)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;
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
// J Front End Example
|
||||
// define _WIN32 for Windows, __MACH__ for MAC, J64 for 64-bit
|
||||
// JE is loaded from current working directory
|
||||
|
||||
//make jfex && LD_LIBRARY_PATH=/usr/local/j64-701/bin ./jfex
|
||||
|
||||
#ifdef _WIN32
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#include <windows.h>
|
||||
#include <direct.h>
|
||||
#define GETPROCADDRESS(h,p) GetProcAddress(h,p)
|
||||
#define JDLLNAME "\\j.dll"
|
||||
#else
|
||||
#define _stdcall
|
||||
#include <dlfcn.h>
|
||||
#define GETPROCADDRESS(h,p) dlsym(h,p)
|
||||
#ifdef __MACH__
|
||||
#define JDLLNAME "/libj.dylib"
|
||||
#else
|
||||
#define JDLLNAME "/libj.so"
|
||||
#endif
|
||||
#define _getcwd getcwd
|
||||
#endif
|
||||
|
||||
#include<stdio.h>
|
||||
#include<signal.h>
|
||||
#include<stdlib.h>
|
||||
#include<string.h>
|
||||
#include"jfex.h"
|
||||
#include"jlib.h"
|
||||
|
||||
static JDoType jdo;
|
||||
static JFreeType jfree;
|
||||
static JgaType jga;
|
||||
static JGetLocaleType jgetlocale;
|
||||
|
||||
static J jt;
|
||||
static void* hjdll;
|
||||
|
||||
static char **adadbreak;
|
||||
static void sigint(int k){**adadbreak+=1;signal(SIGINT,sigint);}
|
||||
static char input[1000];
|
||||
|
||||
// J calls for input (debug suspension and 1!:1[1) and we call for input
|
||||
char* _stdcall Jinput(J jt,char* prompt)
|
||||
{
|
||||
fputs(prompt,stdout);
|
||||
if(fgets(input, sizeof(input), stdin))
|
||||
{
|
||||
fputs("\n",stdout);
|
||||
**adadbreak+=1;
|
||||
}
|
||||
return input;
|
||||
}
|
||||
|
||||
static char*buffer = NULL; /**************************************/
|
||||
static unsigned length = 0; /**************************************/
|
||||
static int Jouts = 0; /**************************************/
|
||||
|
||||
// J calls for output
|
||||
#define LINEFEED 10 /**************************************/
|
||||
void _stdcall Joutput(J jt,int type, char* s) /********************/
|
||||
{
|
||||
size_t L;
|
||||
if(MTYOEXIT==type) exit((int)(I)s);
|
||||
L = strlen(s);
|
||||
L -= (L && (LINEFEED==s[L-1])); /* CRLF not handled. */
|
||||
if (L && (!Jouts)) {
|
||||
length = L;
|
||||
strncpy(buffer,s,L);
|
||||
Jouts = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int Query(char*Data,unsigned*Length)
|
||||
{
|
||||
void* callbacks[] = {Joutput,NULL,Jinput,0,(void*)SMCON};
|
||||
char pathdll[1000];
|
||||
_getcwd(pathdll,sizeof(pathdll));
|
||||
strcat(pathdll,JDLLNAME);
|
||||
#ifdef _WIN32
|
||||
hjdll=LoadLibraryA(pathdll);
|
||||
#else
|
||||
hjdll=dlopen(pathdll,RTLD_LAZY);
|
||||
if (NULL == hjdll)
|
||||
hjdll=dlopen(JDLLNAME+1,RTLD_LAZY); /* use LD_LIBRARY_PATH */
|
||||
#endif
|
||||
if(NULL == hjdll)
|
||||
{
|
||||
fprintf(stderr,"Unix use: $ LD_LIBRARY_PATH=path/to/libj.so %s\n","programName");//*argv);
|
||||
fputs("Load library failed: ",stderr);
|
||||
fputs(pathdll,stderr);
|
||||
fputs("\n",stderr);
|
||||
return 0; // load library failed
|
||||
}
|
||||
jt=((JInitType)GETPROCADDRESS(hjdll,"JInit"))();
|
||||
if(!jt) return 0; // JE init failed
|
||||
((JSMType)GETPROCADDRESS(hjdll,"JSM"))(jt,callbacks);
|
||||
jdo=(JDoType)GETPROCADDRESS(hjdll,"JDo");
|
||||
jfree=(JFreeType)GETPROCADDRESS(hjdll,"JFree");
|
||||
jga=(JgaType)GETPROCADDRESS(hjdll,"Jga");
|
||||
jgetlocale=(JGetLocaleType)GETPROCADDRESS(hjdll,"JGetLocale");
|
||||
adadbreak=(char**)jt; // first address in jt is address of breakdata
|
||||
signal(SIGINT,sigint);
|
||||
{
|
||||
char input[999];
|
||||
//memset(input,0,sizeof input);
|
||||
buffer = Data;
|
||||
sprintf(input,"query %u [ 0!:110<'rc_embed.ijs'\n",*Length); /***deceptive input routine, a hard coded string*********/
|
||||
jdo(jt,input);
|
||||
if (!Jouts)
|
||||
return 0;
|
||||
*Length = length;
|
||||
}
|
||||
jfree(jt);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# jfe makefile info
|
||||
# customize to create makefile suitable for your platform
|
||||
# 32bit builds on 64bit systems require -m32 in CFLAGS and FLAGS
|
||||
# Unix requires -ldl in FLAGS and Windows does not
|
||||
|
||||
CPPFLAGS= -I/usr/local/j64-602/system/examples/jfe
|
||||
CFLAGS= -O0 -g
|
||||
LOADLIBES= -ldl
|
||||
|
||||
main: main.o Query.o
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
$ make main && LD_LIBRARY_PATH=~/Downloads/jgplsrc/j/bin ./main
|
||||
Here am I
|
||||
$
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
Section Header
|
||||
|
||||
+ name := QUERY;
|
||||
- external := `#define main _query_main`;
|
||||
- external := `#define query Query`;
|
||||
|
||||
Section External
|
||||
|
||||
- query(buffer : NATIVE_ARRAY[CHARACTER], size : NATIVE_ARRAY[INTEGER]) : INTEGER <- (
|
||||
+ s : STRING_CONSTANT;
|
||||
+ len, result : INTEGER;
|
||||
s := "Here am I";
|
||||
len := s.count;
|
||||
(len > size.item(0)).if {
|
||||
result := 0;
|
||||
} else {
|
||||
1.to len do { i : INTEGER;
|
||||
buffer.put (s @ i) to (i - 1);
|
||||
};
|
||||
size.put len to 0;
|
||||
result := 1;
|
||||
};
|
||||
result
|
||||
);
|
||||
|
||||
Section Public
|
||||
|
||||
- main <- (
|
||||
+ buffer : NATIVE_ARRAY[CHARACTER];
|
||||
+ size : NATIVE_ARRAY[INTEGER];
|
||||
query(buffer, size); // need this to pull the query() method
|
||||
);
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
TARGET=test_query
|
||||
|
||||
all: $(TARGET)
|
||||
|
||||
$(TARGET): main.o query.o
|
||||
gcc -o $@ main.o query.o
|
||||
|
||||
.c.o:
|
||||
gcc -c $<
|
||||
|
||||
query.c: query.li
|
||||
-lisaac $<
|
||||
|
||||
clean:
|
||||
rm -f $(TARGET) *.o query.c
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <caml/mlvalues.h>
|
||||
#include <caml/callback.h>
|
||||
|
||||
extern int Query (char * Data, size_t * Length)
|
||||
{
|
||||
static value * closure_f = NULL;
|
||||
if (closure_f == NULL) {
|
||||
closure_f = caml_named_value("Query function cb");
|
||||
}
|
||||
value ret = caml_callback(*closure_f, Val_unit);
|
||||
*Length = Int_val(Field(ret, 1));
|
||||
strncpy(Data, String_val(Field(ret, 0)), *Length);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main (int argc, char * argv [])
|
||||
{
|
||||
char Buffer [1024];
|
||||
unsigned Size = 0;
|
||||
|
||||
caml_main(argv); /* added from the original main */
|
||||
|
||||
if (0 == Query (Buffer, &Size))
|
||||
{
|
||||
printf ("failed to call Query\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
char * Ptr = Buffer;
|
||||
printf("size: %d\n", Size);
|
||||
while (Size-- > 0) putchar (*Ptr++);
|
||||
putchar ('\n');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
let caml_query () =
|
||||
let s = "Here am I" in
|
||||
(s, String.length s)
|
||||
;;
|
||||
|
||||
let () =
|
||||
Callback.register "Query function cb" caml_query;
|
||||
;;
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
(let (Str "Here am I" Len (format (opt))) # Get length from command line
|
||||
(unless (>= (size Str) Len) # Check buffer size
|
||||
(prinl Str) ) ) # Return string if OK
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
int Query(char *Data, size_t *Length) {
|
||||
FILE *fp;
|
||||
char buf[64];
|
||||
|
||||
sprintf(buf, "/usr/bin/picolisp query.l %d -bye", *Length);
|
||||
if (!(fp = popen(buf, "r")))
|
||||
return 0;
|
||||
fgets(Data, *Length, fp);
|
||||
*Length = strlen(Data);
|
||||
return pclose(fp) >= 0 && *Length != 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# store this in file rc_embed.py
|
||||
# store this in file rc_embed.py
|
||||
def query(buffer_length):
|
||||
message = b'Here am I'
|
||||
L = len(message)
|
||||
return message[0:L*(L <= buffer_length)]
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#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>
|
||||
|
||||
extern int Query(char*,unsigned*);
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
#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 {
|
||||
if (! PyBytes_Size(pResult))
|
||||
result = 0;
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
$ 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
|
||||
$
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
int Query (char * Data, size_t * Length) {
|
||||
Tcl_Obj *arguments[2];
|
||||
int code;
|
||||
|
||||
arguments[0] = Tcl_NewStringObj("Query", -1); /* -1 for "use up to zero byte" */
|
||||
arguments[1] = Tcl_NewStringObj(Data, Length);
|
||||
Tcl_IncrRefCount(arguments[0]);
|
||||
Tcl_IncrRefCount(arguments[1]);
|
||||
if (Tcl_EvalObjv(interp, 2, arguments, 0) != TCL_OK) {
|
||||
/* Was an error or other exception; report here... */
|
||||
Tcl_DecrRefCount(arguments[0]);
|
||||
Tcl_DecrRefCount(arguments[1]);
|
||||
return 0;
|
||||
}
|
||||
Tcl_DecrRefCount(arguments[0]);
|
||||
Tcl_DecrRefCount(arguments[1]);
|
||||
if (Tcl_GetObjResult(NULL, Tcl_GetObjResult(interp), &code) != TCL_OK) {
|
||||
/* Not an integer result */
|
||||
return 0;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
proc Query data {
|
||||
puts "Query was $data"
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
int Query (char * Data, size_t * Length) {
|
||||
const char *str;
|
||||
int len;
|
||||
|
||||
if (Tcl_Eval(interp, "Query") != TCL_OK) {
|
||||
return 0;
|
||||
}
|
||||
str = Tcl_GetStringFromObj(Tcl_GetObjResult(interp), &len);
|
||||
if (len+1 > Length) {
|
||||
return 0;
|
||||
}
|
||||
memcpy(Data, str, len+1);
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
proc Query {} {
|
||||
return "Here am I"
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
#include <tcl.h>
|
||||
Tcl_Interp *interp;
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
Tcl_FindExecutable(argv[0]); /* Initializes library */
|
||||
interp = Tcl_CreateInterp(); /* Make an interpreter */
|
||||
|
||||
/* Rest of contents of main() from task header... */
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue