Initial Release
The simpest example of how to build/use IRIS Callin and Callout.
It covers various functions such as
Callin (callin_misc) will perform various access. Unicode test is using Japanese as an example. See log section below.
Multi-thread Callin (callin_multithreads) will set ^callinMT global nodes from within each thread.
Callout (callout.so) will add two given integers and returns it.
It dosen’t cover $List structure handling because it is not provide by InterSystems.
see
https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=BXCI
https://docs.intersystems.com/irislatest/csp/docbook/Doc.View.cls?KEY=BGCL_library
Verified under
IRIS for Windows (x86-64) 2020.1 (Build 215U) Mon Mar 30 2020 20:14:33 EDT
IRIS for UNIX (Ubuntu Server LTS for x86-64) 2020.1 (Build 215U) Mon Mar 30 2020 20:25:33 EDT
This sample involves unicode handling (primarily for Japanese but should work against any).
If it matters, please change following parts in Dockerfile, to meet your environment.
RUN echo 'export LANG=ja_JP.UTF-8' >> ~/.bashrc && echo 'export LANGUAGE="ja_JP:ja"' >> ~/.bashrc \
&& printf 'Do ##class(Config.NLS.Locales).Install("jpuw") h\n' | iris session $ISC_PACKAGE_INSTANCENAME -U %SYS \
Nothing to do except starting IRIS. Everything is ready to go, then.
user@host:~/$ git clone https://github.com/IRISMeister/iris-c-language.git
user@host:~/$ cd iris-c-language
user@host:~/iris-c-language$ docker compose up -d
user@host:~/iris-c-language$ docker compose exec iris bash
irisowner@ec21549f2063:~$
If you edit c source code, you need to rebuild an image to reflect those changes.
(because I wanted to compile c source codes during container image build time, not afterwards)
user@host:~/iris-c-language$ docker compose build
Or copy them (from srcext folder) to src folder and ‘make’ it.
user@host:~/iris-c-language$ docker compose exec iris bash
irisowner@ec21549f2063:~$ cd src
irisowner@ec21549f2063:~/src$ cp ../srcext/*.c .
irisowner@ec21549f2063:~/src$ make
See Windows section.
irisowner@9618c833d390:~$ cd src
irisowner@9618c833d390:~/src$ ./callin_misc
IRISSETDIR rc:0
IRISSECURESTART Status :Success. 0
maxrss=8832
========= Calling callin_routine_call
IRISPUSHRTN rc:0
IRISDORTN rc:0
========= Calling callin_function_call1
IRISPUSHRTN rc:0
IRISPUSHINT rc:0
IRISEXTFUN rc:0
IRISPOPINT rc:0
return value as INT4 :123
========= Calling callin_function_call1a
IRISPUSHRTN rc:0
IRISPUSHINT rc:0
IRISEXTFUN rc:0
IRISPOPINT rc:0
return value as INT64 :4611686018427387904
========= Calling callin_function_call2
IRISPUSHRTN rc:0
IRISEXTFUN rc:0
IRISPOPSTR rc:0
len:7
return value as STRING :abcdefg
========= Calling callin_routine_geterrorinfo
IRISPUSHRTN rc:0
IRISDORTN rc:18
IRISERRXLATE []
IRISERROR [ErrorEntry+1^TestRoutine]
IRISERROR [ Set a=1/0]
IRISERROR [1]
========= Calling callin_classmethod_call1
IRISPUSHCLASSMETHOD rc:0
IRISINVOKECLASSMETHOD rc:0
========= Calling callin_classmethod_call2
IRISPUSHCLASSMETHOD rc:0
IRISPUSHINT rc:0
IRISINVOKECLASSMETHOD rc:0
IRISPOPINT rc:0
return value as INT4 :456
========= Calling callin_classmethod_call3
IRISPUSHCLASSMETHOD rc:0
IRISINVOKECLASSMETHOD rc:0
IRISPOPSTR rc:0
len:3
return value as STRING :ABC
========= Calling callin_classmethod_call4
IRISPUSHCLASSMETHOD rc:0
IRISINVOKECLASSMETHOD rc:0
IRISPOPEXSTR rc:0
len:1000000
return value as STRING :AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA....
IRISEXSTRKILL rc:0
========= Calling callin_globals_set_and_get
IRISPUSHGLOBAL rc:0
IRISGLOBALGET rc:0
IRISPOPSTR rc:0
len:3
value:abc
IRISPUSHGLOBAL rc:0
IRISPUSHINT rc:0
IRISGLOBALGET rc:0
IRISPOPSTR rc:0
len:5
value:12345
========= Calling callin_execute
========= Setting Unicode Value.
locale ja_JP.UTF-8.
IRISPUSHGLOBAL rc:0
IRISPUSHINT rc:0
Pushing ... value:あいうえお length:5 size of one letter:4
IRISPUSHSTRH rc:0
IRISGLOBALSET rc:0
========= Setting long ascii String.
strlen 1000000
IRISPUSHGLOBAL rc:0
IRISPUSHINT rc:0
IRISPUSHEXSTR rc:0
IRISGLOBALSET rc:0
IRISEXSTRKILL rc:0
========= Setting long Unicode String.
wcslen 1000000
IRISPUSHGLOBAL rc:0
IRISPUSHINT rc:0
IRISPUSHEXSTRH rc:0
IRISGLOBALSET rc:0
IRISEXSTRKILL rc:0
maxrss=21324
Exiting.
irisowner@9618c833d390:~/src$
irisowner@9618c833d390:~/src$ iris session iris -U demo
ノード: 9618c833d390 インスタンス: IRIS
DEMO>d ##class(Verify).CheckResults() OK DEMO>zw ^test ^test="abc" ^test(1)=12345 ^test("MyClassMethod1")="09/18/2020 16:22:57" ^test("MyClassMethod2")="09/18/2020 16:22:57;my ascii string data;100" ^test("MyClassMethod3")="09/18/2020 16:22:57;my ascii string data" ^test("MyClassMethod4",1)="09/18/2020 16:22:57" ^test("MyClassMethod4",2)="my ascii string data"
DEMO>zw ^test2
^test2(1)="abc"
^test2(2)="abc"
^test2(3)="abc"
^test2(4)="abc"
^test2(5)="abc"
^test2(6)="abc"
^test2(7)="abc"
^test2(8)="abc"
^test2(9)="abc"
^test2(10)="abc"DEMO>zw ^calltest
^calltest(1)="09/18/2020 16:22:57"
^calltest(2)="09/18/2020 16:22:57;my ascii string data;100"
^calltest(3)="09/18/2020 16:22:57;my ascii string data"DEMO>zw ^execute
^execute=1
^execute(1)="09/18/2020 16:22:57/572"DEMO>zw ^unicode
^unicode(1)="あいうえお"
DEMO>w $L(^long(1))
1000000
DEMO>w $E(^long(1),$L(^long(1))-10,)
AAAAAAAAAAA
DEMO>w $L(^long(2))
1000000
DEMO>w $E(^long(2),$L(^long(2))-10,)
あああああああああああ
DEMO>h
It creates three threads. You can stop callin_multithreads by Ctrl-c.
irisowner@ec21549f2063:~/src$ ./callin_multithreads Starting main process. #140432145268544 Starting thread_noiris_main #140432109364992 IRISSETDIR rc:0 Thread(0) #140432100972288 starting authentication in IRIS' Thread(1) #140432092579584 starting authentication in IRIS' Waiting for threads to exit... Thread(2) #140432084186880 starting authentication in IRIS' Thread(1) #140432092579584 starting test Thread(0) #140432100972288 starting test Thread(2) #140432084186880 starting test ^CSignal caught by #140432145268544 <= wait a moment and type Ctrl-c to interrupt si_signo:2 si_code:128 si_pid:0 si_uid:0 Ending thread_noiris_main #140432109364992 Thread(2) #140432084186880 has completed test Thread(2) #140432084186880 leaving IRIS' Thread(2) #140432084186880 exiting Thread(1) #140432092579584 has completed test Thread(1) #140432092579584 leaving IRIS' Thread(1) #140432092579584 exiting Thread(0) #140432100972288 has completed test Thread(0) #140432100972288 leaving IRIS' Thread(0) #140432100972288 exiting Join th2 All threads have exited - done irisowner@ec21549f2063:~/src$ irisowner@ec21549f2063:~/src$ iris session iris -U demo
ノード: ec21549f2063 インスタンス: IRIS
DEMO>zw ^callinMT
^callinMT=4 <== node counts varies depending on how long you'd waited before stop it.
^callinMT(1)="threadId:140432100972288 @ 2020/06/04 Thu 17:20:35"
^callinMT(2)="threadId:140432084186880 @ 2020/06/04 Thu 17:20:36"
^callinMT(3)="threadId:140432092579584 @ 2020/06/04 Thu 17:20:37"
^callinMT(4)="threadId:140432100972288 @ 2020/06/04 Thu 17:20:40"
DEMO>
“AddInt” adds given two numeric values.
“AddIntSave” does the same and then save it to a global. (a combination of callout and callin)
“CallRoutine” calls a routine which access local variable ‘MYLOCALVAR’ and return as a string value.
DEMO>w $ZF(-3,"/home/irisowner/src/callout.so","AddInt",2,3)
5
DEMO>w $ZF(-3,"/home/irisowner/src/callout.so","AddIntSave",3,8)
11
DEMO>zw ^callout
^callout(1)=11
DEMO>w $ZF(-3,"/home/irisowner/src/callout.so","CallRoutine")
UNDEF
W $ZF(-3,"home/irisowner/src/callout.so","CallRoutine")
^
DEMO>s MYLOCALVAR="abcdefg"
DEMO>w $ZF(-3,"/home/irisowner/src/callout.so","CallRoutine")
return value as STRING :abcdefg
DEMO>h
irisowner@ec21549f2063:~/src$ exit
exit
user@host:~/iris-c-language$
user@host:~/iris-c-language$ docker compose down
If you want to run callin programs against non-container version of IRIS, you need to execute it as user ‘irisowner’ or whatever user which belongs to the group you picked when you installed IRIS.
$ sudo -u irisowner ./callin_misc
or
$ sudo ./callin_misc
If you want to build and run these examples on Windows, you need to setup some manually.
Assuming IRIS is installed under C:\InterSystems\IRIS\
USER>Set ^test="abc",^test(1)=12345
C:\temp>git clone https://github.com/IRISMeister/iris-c-language.git
C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional>cd \temp\iris-c-language\src
C:\temp\iris-c-language\src>nmake -f makefile.mak
C:\temp\iris-c-language\src>Set Path=C:\InterSystems\IRIS\bin;%Path%
C:\temp\iris-c-language\src>x64\callin_misc.exe
C:\temp\iris-c-language\src>x64\callin_multithreads.exe
For callout, use the following dll.
DEMO>w $ZF(-3,"c:\temp\src\callout.dll","AddInt",2,3)
If you get C4819 error while compiling callin_misc_value.c, make sure it is saved as UTF8 with BOM.
makefile-cache.mak, callin_multithreads-cache.c, callout-cache.c are for Cache’ build.
You can build it by following command if you have appropriate Cache’ files.
C:\temp\iris-c-language\src>nmake -f makefile-cache.mak
If you are migrating such existing callin/callout programs from Cache’ to IRIS, you can build them for IRIS by simply modifying several lines.
makefile-cache.mak
Change include files location.
/I"..\\" /I"C:\InterSystems\Cache\dev\callin"
/I"..\\" /I"C:\InterSystems\IRIS\dev\iris-callin\include"
Change library files location.
/DYNAMICBASE:NO "cachet.lib" \
/LIBPATH:"C:\InterSystems\Cache\bin"
/DYNAMICBASE:NO "irisdbt.lib" \
/LIBPATH:"C:\InterSystems\IRIS\dev\iris-callin\lib"
shdir-cache.c
Change installation path.
char *shdir="C:\\InterSystems\\CACHE\\mgr";
char *shdir="C:\\InterSystems\\IRIS\\mgr";
You probably need to use the same or higher gcc compiler version.
How to check IRIS compiler version.
irisowner@2ba56e3fa18e:~$ objdump -sj .comment /usr/irissys/bin/irisdb
/usr/irissys/bin/irisdb: ファイル形式 elf64-x86-64
セクション .comment の内容:
0000 4743433a 20285562 756e7475 2031312e GCC: (Ubuntu 11.
0010 322e302d 31397562 756e7475 31292031 2.0-19ubuntu1) 1
0020 312e322e 3000 1.2.0.
How to check current compiler version.
irisowner@2ba56e3fa18e:~$ gcc --version
gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
How to analyze core dump
irisowner@da909659f959:~$ cd DEMO
irisowner@da909659f959:~/DEMO$ ls
IRIS.DAT core.1064 iris.lck stream
irisowner@da909659f959:~/DEMO$ gdb /usr/irissys/bin/irisdb ./core.1064
(gdb) bt