Addons/general/pcall

From J Wiki
Jump to: navigation, search
User Guide | Installation | Development | Categories | Git | Build Log

Pointer call is a DLL function call, where function is referred to by its memory location.

See also: examples in SVN folder; change history.


Applications of pointer call are when the function is not part of dll map. For example

  • callback, we are given a function address and need to call it, as in OpenGL shader
  • function address is a part of a known struct, such as Java JNI and AWT JNI
  • calling a method from vtable of an interface pointer

Interface pointer is an object reference as implemented in C++ (this pointer) and COM. Given pointer to object p and vt-index (vtable index) i to get function address we say in C p[0][i]. To call a C++ or COM method we say (omitting type casts) r = p[0][i](p,...);.

cd (15!:0) accepts the following signature 'module entry ...', where

  • module is dll name
  • entry is function name in dll map or index if it has the form #123

It is proposed to recognize additional meanings:

  • module=0 then entry is function pointer
  • module=1 then entry is vtable index from interface pointer in first argument

All other conventions, such as %, etc. would still apply. In summary, cf Calling DLLs in User Manual.

'name.dll fname i i ...' cd ...    NB. by func name
'name.dll #123  i i ...' cd ...    NB. by func index 123
'0        12345 i i ...' cd ...    NB. by func ptr 12345
'1        123   i i ...' cd p,..   NB. by vt-index 123 of object p

Note: module as other numeric is reserved for future use

Pointer Call Demo

As a proof of concept, but good enough to use in applications, here is an example of such use as emulated by the general/pcall addon. It shows a dll pcall that emulates pointer call, and vtable address resolved in J. We demonstrate how pointer call gives the same fluency in COM programming as in C or C++.

Note: these explicit calls to COM and Automation API are shown here for demonstration. For practical reasons, they could be all wrapped in a nice API in J. In addition, for particular known components J class wrappers can be created.

There is no reason why using this approach the wd 'ole...' could not be replaced with regular J code using the extended DLL calling conventions. The order of complexity should not exceed that of the memory mapped files implementation.

Interface pointers are not confined to COM and Windows only, for example Apple Plugin API for Mac OS X and Mozilla XPCOM for Netscape and Firefox use them too.

Calling a J Method

Here we call J method DoR with parameter i.3 4.

Wm yes check.png

/test pcall

Dynamic Discovery of Type Information

Here we discover the number of functions in J interface (25) and the name of a specific function IsBusy using ITypeInfo interface.

Wm yes check.png

/test typeinfo

Interface Call

pcall addon has been enhanced to emulate module=1 proposed case. For example, cd signature to call interface with 3-argument function is
   'pcall ci3 i i i i i i' types are result,vt-index,this, arg1,arg2,arg3

The call looks like this, where jiDoR is simply vt-index integer
   'ci3 > i i i *w *i *i' pcall jiDoR;J;'9!:14$0';res;,_2

Wm yes check.png

/test icall

COM Call

Finally we can make wrappers to COM interface functions using interface call and position in the interface table. Now the call looks much like in Visual Basic
   J ijDoR '9!:14$0' ; res ; ,_2

Note, such wrapper functions can be automatically generated using the TypeInfo discovery mechanism provided by IDispatch from live object or using COM API from DLL.

Wm yes check.png

/test comcall

IDispatch Class

One more thing... To showcase the true power of interface call, we create a cover class pdisp which replaces the wd'ole...' commands with Visual Basic style calling, i.e. more natural object-oriented instance handling, passing regular parameters (not all as one string) and automatic conversion of between J and COM variant types.

Wm yes check.png

/test disp

See Also