Here's a working example of the definition below.
It runs on Windows and with small modification can run
on Unices. Latest pcall addon update has Linux and Mac libs.
// jcallback.cpp : Call function defined in C from J
//
#include <stdio.h>
#include <windows.h>
typedef int jhandle_t, jresult_t;
#define JCALL(t,f) typedef t (__stdcall *f##_t)
JCALL(jhandle_t, JInit)();
JCALL(jresult_t, JFree)(jhandle_t j);
JCALL(jresult_t, JDo) (jhandle_t j, const char *input);
JCALL(jresult_t, JGetM)(jhandle_t j, char *name, int* type, int* rank, int**
shape, void** data);
JCALL(jresult_t, JSetM)(jhandle_t j, char *name, int* type, int* rank, int**
shape, void** data);
JInit_t JInit;
JFree_t JFree;
JSetM_t JSetM;
JGetM_t JGetM;
JDo_t JDo;
int sum(int *y, int n) {
int r = 0;
for ( ; n-- ; ) r += *y++;
return r;
}
int main(int argc, char* argv[])
{
HMODULE hm = LoadLibrary(L"j.dll");
jhandle_t jh = 0, res = 0;
int a1[] = {1,2,3,4}, s1;
int t, r, *s, *a;
JInit = (JInit_t) GetProcAddress(hm, "JInit");
JFree = (JFree_t) GetProcAddress(hm, "JFree");
JSetM = (JSetM_t) GetProcAddress(hm, "JSetM");
JGetM = (JGetM_t) GetProcAddress(hm, "JGetM");
JDo = (JDo_t) GetProcAddress(hm, "JDo");
jh = JInit();
t = 4; r = 1; s1 = 4; s = &s1; a=a1;
JSetM(jh, "a1", &t, &r, &s, &a);
JDo(jh, "b1=: +/a1");
JGetM(jh, "b1", &t, &r, &s, &a);
printf(" +/ a1 = %d\n", *a);
printf("sum(a1) = %d in C\n", sum(a1, 4));
t = 4, r = 0, s1 = 0, s = &s1, a=(int*)sum;
JSetM(jh, "sumf", &t, &r, &s, &a);
JDo(jh, "load 'general/pcall'");
JDo(jh, "sum=: [: 'cc2 > + i i *i i' pcall sumf ; (; #)");
JDo(jh, "b1=: sum a1");
JGetM(jh, "b1", &t, &r, &s, &a);
printf("sum(a1) = %d in J\n", *a);
res = JFree(jh);
return 0;
}
--- Oleg Kobchenko <[EMAIL PROTECTED]> wrote:
> There is a difference between J external API and that
> of K, Java, etc. in that J API operates in C native
> types and arrays, and does not attempt to spread the
> ownership of J objects outside of J scope.
>
> Such approach is simpler, and more portable with existing
> and other C code, because it does not impose the
> memory management details of the scripting engine to
> the native code.
>
> Among other things it enables to interoperate J and
> native code more directly without much of the glue
> code such as JNI or importing special headers with
> many housekeeping functions--it just works with
> native C types and arrays.
>
> Although in some implementations there may be accessors
> like SetA/GetA for J array, they are not necessary
> for any kinds of tasks. SetM/GetM work with native arrays.
>
> There are many examples of external interops at the Wiki
>
> http://www.jsoftware.com/jwiki/Interfaces
>
>
> --- Oleg Kobchenko <[EMAIL PROTECTED]> wrote:
>
> > Leaving out the details of the many little obscure functions, what I was
> > able
> > to figure put is that
> > - you have a C main app, where you
> > - define function sum (of int array returning int scalar) and pass it to J
> > - form int array and pass it to J
> > - invoke sum over array in J
> > - return result to C
> >
> > Right?
> >
> > Oleg Kobchenko
> >
> >
> > On Jul 17, 2007, at 9:43 PM, "Jack Andrews" <[EMAIL PROTECTED]> wrote:
> >
> > oleg wrote:
> > could you just provide a simple concrete use case or two
> > with actual function signatures on all layers involved.
> >
> > here's my use case, with header file defining the API.
> > i'm working on implementing the API given the current C API.
> > documentation on the API is available here:
> > http://kx.com/a/k/connect/c/CandK.txt
> >
> > J sum(J x)
> > {int z=0,i=0;assert(x->t==4&&x->r==1);
> > for(;i<x->s[0];i++)z+=x->d[i];return gi(z);
> > }
> > main()
> > {cd(jsj("",0));
> > sfn("sum",(J(*)(void))sum,1);
> > {C b[99];while(gets(b))
> > {J r=jsj(b,0);
> > if(Nt==r->t&&NULL!=r->d)eO("! %s\n",r->d);else show(r);
> > cd(r);
> > }}}
> >
> > header file:
> > /* http://kx.com/a/k/connect/c/k20.h */
> > #define R return
> > #define O printf
> > #define Z static
> > #define DO(n,x) {I i=0,_i=(n);for(;i<_i;++i){x;}}
> > typedef int I;typedef double F;typedef char C;typedef C*S;
> > typedef struct j0{I c,t,r,*s,*d;}*J;
> >
> > /* atom accessors, e.g. Ji(x)=2 */
> > #define Ji(x) (*JI(x))
> > #define Jf(x) (*JF(x))
> > #define Jc(x) (*JC(x))
> > #define Js(x) (*JS(x))
> > /* list accessors, e.g. JF(x)[i]=2.0 */
> > #define JI(x) ((I*)((x)->d))
> > #define JF(x) ((F*)((x)->d))
> > #define JC(x) ((C*)((x)->d))
> > #define JS(x) ((S*)((x)->d))
> >
> > #ifdef __cplusplus
> > extern "C" {
> > #endif
> >
> > extern S sp(S); /* symbol from phrase */
> >
> > /* atom generators, e.g. gi(2),gf(2.0),gc('2'),gs(sp("2")) */
> > extern J gi(I),gf(F),gc(C),gs(S),gn(void);
> >
> > /* list generator (t as in 4::), e.g. gtn(-1,9) integer vector */
> > extern J gtn(I t,I n);
> >
> > /* phrase (-3=4::) generators, e.g. gp("asdf");C*s;gpn(s,4); */
> > extern J gp(S),gpn(S,I);
> >
> > /* error, e.g. if(x->t!=-1)return jerr("need integer vector");*/
> > extern J jerr(S),gsj(S,J),gnj(I,...),ci(J),jsj(S,J),jap(J*,void*);
> > extern I cd(J),jd(I),dj(I),scd(I),sdf(I,I(*)(void)),sfn(S,J(*)(void),I);
> >
> > #ifdef __cplusplus
> > }
> > #endif
>
>
>
>
>
> ____________________________________________________________________________________
> Fussy? Opinionated? Impossible to please? Perfect. Join Yahoo!'s user panel
> and lay it on us.
> http://surveylink.yahoo.com/gmrs/yahoo_panel_invite.asp?a=7
>
> ----------------------------------------------------------------------
> For information about J forums see http://www.jsoftware.com/forums.htm
>
____________________________________________________________________________________
Never miss an email again!
Yahoo! Toolbar alerts you the instant new Mail arrives.
http://tools.search.yahoo.com/toolbar/features/mail/
----------------------------------------------------------------------
For information about J forums see http://www.jsoftware.com/forums.htm