チュートリアル: C/C++ による拡張機能の開発方法

Ring プログラムで C コードを用いるための簡単な用例です。

Hello World

サンプル : ring/extensions/tutorial/helloworld

ファイル mylib.c の内容

#include "ring.h"

#include "stdlib.h"

RING_FUNC(ring_myfunction)
{
        printf("Hello, World!");
}

RING_API void ringlib_init(RingState *pRingState)
{
        ring_vm_funcregister("myfunction",ring_myfunction);
}

ソースコードを参照すると、最初の行で Ring API の定義を記した ring.h ファイルをインクルードしています。

新規関数の定義に RING_FUNC マクロを使います。通常の C 関数とは異なる定義であることを識別しやすくするために関数定義の接頭辞にring_を付けるのは良い考えです。

Ring VM で拡張機能が読み込まれるときに呼び出される関数 ringlib_init() があります。

この関数では Ring VM へ新規関数を登録するために ring_vm_funcregister() を使用します。

拡張機能をビルドするには :

buildvc.bat

buildvc.bat ファイルの内容には Visual C/C++ で拡張機能をビルドするためのコマンドが記述されています

cls
call ../../../src/locatevc.bat
cl /c /DEBUG mylib.c -I"..\..\..\include"
link /DEBUG mylib.obj  ..\..\..\lib\ring.lib /DLL /OUT:mylib.dll /SUBSYSTEM:CONSOLE,"5.01"
del mylib.obj

関数のテスト

ring test.ring

ファイル test.ring の内容

? "Loading Library"
loadlib("mylib.dll")

? "Calling a C Function"
myfunction()

実行結果

Loading Library
Calling a C Function
Hello, World!

異動作環境間での機能拡張のビルド

サンプル : ring/extensions/tutorial/helloworld2

この拡張機能は前述のものですが、 Windows, Linux および macOS に対応させます。

このファイルを使用します

buildvc.bat
buildgcc.sh
buildclang.sh

Windows では buildvc.bat を、 Linux では buildgcc.sh および macOS では buildclang.sh でビルドします。

ファイル buildgcc.sh には下記の内容が記述されています

gcc -c -fpic mylib.c -I $PWD/../../../include
gcc -shared -o libmylib.so mylib.o -L $PWD/../../../lib -lring
sudo cp libmylib.so /usr/lib
sudo cp libmylib.so /usr/lib64

ファイル buildclang.sh の内容

clang -c -fpic mylib.c -I $PWD/../../../include
clang -dynamiclib -o libmylib.dylib mylib.o  -L $PWD/../../../lib  -lring
cp libmylib.dylib /usr/local/lib

動作環境別にライブラリの読み込み対象を変更するために mylib.ring から LoadLib() 関数を呼び出します。

mylib.ringのコード内容は

if iswindows()
        LoadLib("mylib.dll")
but ismacosx()
        LoadLib("libmylib.dylib")
else
        LoadLib("libmylib.so")
ok

ファイル test.ring の内容

? "Loading Library"
load "mylib.ring"

? "Calling a C Function"
myfunction()

関数のテスト

ring test.ring

実行結果

Loading Library
Calling a C Function
Hello, World!

二数値の合計

サンプル : ring/extensions/tutorial/sumtwonumbers

この拡張機能では二数値を合計する C 関数の作成方法です。

これは Hello World 2 拡張機能の更新版です : ring/extensions/tutorial/helloworld2 フォルダ

ファイル mylib.c を変更します

RING_FUNC(ring_sumtwonumbers)
{
        double nNum1,nNum2,nSum;
        // 引数の個数を検査します
                if (RING_API_PARACOUNT != 2) {
                        RING_API_ERROR(RING_API_MISS2PARA);
                        return;
                }
        // 引数の型を検査します
                if ( ! (RING_API_ISNUMBER(1) && RING_API_ISNUMBER(2)) ) {
                        RING_API_ERROR(RING_API_BADPARATYPE);
                        return;
                }
        // 数値の総和
                nNum1 = RING_API_GETNUMBER(1);
                nNum2 = RING_API_GETNUMBER(2);
                nSum  = nNum1 + nNum2 ;
        // 処理結果を返します
                RING_API_RETNUMBER(nSum);
}

関数を新規登録します

ring_vm_funcregister("sumtwonumbers",ring_sumtwonumbers);

前述コードは理解しやすく、エラーの確認が容易になるように記述してあります。

略記もできます

RING_API_RETNUMBER(RING_API_GETNUMBER(1) + RING_API_GETNUMBER(2));

ファイル test.ring の内容

? "Loading Library"
load "mylib.ring"

? "Calling a C Function"
myfunction()

? "Sum Two Numbers (3,5)"
? SumTwoNumbers(3,5)

関数のテスト

ring test.ring

実行結果

Loading Library
Calling a C Function
Hello, World!
Sum Two Numbers (3,5)
8

Say Hello

サンプル : ring/extensions/tutorial/sayhello

この拡張機能では文字列として名前を取得してから say hello を表示する C 関数の作成方法です。

これは sumtwonumbers 拡張機能の更新版です : ring/extensions/tutorial/sumtwonumbers フォルダ

ファイル mylib.c を変更します

RING_FUNC(ring_sayhello)
{
        // 引数の個数を検査します
                if (RING_API_PARACOUNT != 1) {
                        RING_API_ERROR(RING_API_MISS1PARA);
                        return;
                }
        // 引数の型を検査します
                if ( ! RING_API_ISSTRING(1) ) {
                        RING_API_ERROR(RING_API_BADPARATYPE);
                        return;
                }
        printf("Hello %s\n",RING_API_GETSTRING(1));
}

関数を新規登録します

ring_vm_funcregister("sayhello",ring_sayhello);

ファイル test.ring の内容

? "Loading Library"
load "mylib.ring"

? "Calling a C Function"
myfunction()

? "Sum Two Numbers (3,5)"
? SumTwoNumbers(3,5)

? "Say Hello"
SayHello("Mahmoud")

関数のテスト

ring test.ring

実行結果

Loading Library
Calling a C Function
Hello, World!
Sum Two Numbers (3,5)
8
Say Hello
Hello Mahmoud

数値リストの総和

サンプル : ring/extensions/tutorial/sumlist

この拡張機能では数値リストの総和を行う C 関数の作成方法です。

これは sayhello 拡張機能の更新版です : ring/extensions/tutorial/sayhello フォルダ

ファイル mylib.c を変更します

RING_FUNC(ring_sumlist)
{
        List *pList;
        int x,nSum;
        // 引数の個数を検査します
                if (RING_API_PARACOUNT != 1) {
                        RING_API_ERROR(RING_API_MISS1PARA);
                        return;
                }
        // 引数の型を検査します
                if ( ! RING_API_ISLIST(1) ) {
                        RING_API_ERROR(RING_API_BADPARATYPE);
                        return;
                }
        // 数値リストの総和
                nSum = 0;
                pList = RING_API_GETLIST(1);
                for(x=1 ; x <= ring_list_getsize(pList) ; x++) {
                        if ( ring_list_isdouble(pList,x) ) {
                                nSum += (int) ring_list_getdouble(pList,x) ;
                        }
                }
        // 処理結果を返します
                RING_API_RETNUMBER(nSum);
}

関数を新規登録します

ring_vm_funcregister("sumlist",ring_sumlist);

ファイル test.ring の内容

? "Loading Library"
load "mylib.ring"

? "Calling a C Function"
myfunction()

? "Sum Two Numbers (3,5)"
? SumTwoNumbers(3,5)

? "Say Hello"
SayHello("Mahmoud")

? "Sum List contains numbers from 1 to 10"
aList = 1:10
? SumList(aList)

関数のテスト

ring test.ring

実行結果

Loading Library
Calling a C Function
Hello, World!
Sum Two Numbers (3,5)
8
Say Hello
Hello Mahmoud
Sum List contains numbers from 1 to 10
55

リスト項目の増分

サンプル : ring/extensions/tutorial/incrementlist

この拡張機能ではリスト項目の増分を行う C 関数の作成方法です。

これは sumlist 拡張機能の更新版です : ring/extensions/tutorial/sumlist フォルダ

ファイル mylib.c を変更します

RING_FUNC(ring_inclist)
{
        List *pList;
        int x,nSum;
        // 引数の個数を検査します
                if (RING_API_PARACOUNT != 2) {
                        RING_API_ERROR(RING_API_MISS2PARA);
                        return;
                }
        // 引数の型を検査します
                if ( ! ( RING_API_ISLIST(1) && RING_API_ISNUMBER(2) ) ) {
                        RING_API_ERROR(RING_API_BADPARATYPE);
                        return;
                }
        // リスト項目の増分
                nSum = 0;
                pList = RING_API_GETLIST(1);
                for(x=1 ; x <= ring_list_getsize(pList) ; x++) {
                        if ( ring_list_isdouble(pList,x) ) {
                                ring_list_setdouble(pList,x,
                                        ring_list_getdouble(pList,x)+
                                        RING_API_GETNUMBER(2)) ;
                        }
                }
        // 処理結果を返します
                RING_API_RETLIST(pList);
}

関数を新規登録します

ring_vm_funcregister("inclist",ring_inclist);

ファイル test.ring の内容

? "Loading Library"
load "mylib.ring"

? "Calling a C Function"
myfunction()

? "Sum Two Numbers (3,5)"
? SumTwoNumbers(3,5)

? "Say Hello"
SayHello("Mahmoud")

? "Sum List contains numbers from 1 to 10"
aList = 1:10
? SumList(aList)

? "Increment List Items"
? inclist(aList,10)

関数のテスト

ring test.ring

実行結果

Loading Library
Calling a C Function
Hello, World!
Sum Two Numbers (3,5)
8
Say Hello
Hello Mahmoud
Sum List contains numbers from 1 to 10
55
Increment List Items
11
12
13
14
15
16
17
18
19
20

リスト項目の篩い分け

サンプル : ring/extensions/tutorial/filterlist

この拡張機能ではリスト項目を篩い分ける C 関数の作成方法です。

これは incrementlist 拡張機能の更新版です : ring/extensions/tutorial/incrementlist フォルダ

ファイル mylib.c を変更します

RING_FUNC(ring_filterlist)
{
        List *pList;
        int x;
        // 引数の個数を検査します
                if (RING_API_PARACOUNT != 2) {
                        RING_API_ERROR(RING_API_MISS2PARA);
                        return;
                }
        // 引数の型を検査します
                if ( ! ( RING_API_ISLIST(1) && RING_API_ISNUMBER(2) ) ) {
                        RING_API_ERROR(RING_API_BADPARATYPE);
                        return;
                }
        // リスト項目の篩い分け
                pList = RING_API_GETLIST(1);
                for(x = ring_list_getsize(pList) ; x >= 1 ; x--)
                        if ( ring_list_isdouble(pList,x) )
                                if ( ! (ring_list_getdouble(pList,x) >
                                                 RING_API_GETNUMBER(2)) )
                                        ring_list_deleteitem(pList,x) ;
        // 処理結果を返します
                RING_API_RETLIST(pList);
}

関数を新規登録します

ring_vm_funcregister("filterlist",ring_filterlist);

ファイル test.ring の内容

? "Loading Library"
load "mylib.ring"

? "Calling a C Function"
myfunction()

? "Sum Two Numbers (3,5)"
? SumTwoNumbers(3,5)

? "Say Hello"
SayHello("Mahmoud")

? "Sum List contains numbers from 1 to 10"
aList = 1:10
? SumList(aList)

? "Increment List Items"
? inclist(aList,10)

? "Filter List Items (Items > 15)"
? filterlist(aList,15)

関数のテスト

ring test.ring

実行結果

Loading Library
Calling a C Function
Hello, World!
Sum Two Numbers (3,5)
8
Say Hello
Hello Mahmoud
Sum List contains numbers from 1 to 10
55
Increment List Items
11
12
13
14
15
16
17
18
19
20


Filter List Items (Items > 15)
16
17
18
19
20

リスト項目の複製

サンプル : ring/extensions/tutorial/replicatelist

この拡張機能ではリストへ複数の項目を追加する C 関数の作成方法です。

これは filterlist 拡張機能の更新版です : ring/extensions/tutorial/filterlist フォルダ

ファイル mylib.c を変更します

RING_FUNC(ring_replicatelist)
{
        List *pList;
        int x,y,nTimes,nSize;
        // 引数の個数を検査します
                if (RING_API_PARACOUNT != 2) {
                        RING_API_ERROR(RING_API_MISS2PARA);
                        return;
                }
        // 引数の型を検査します
                if ( ! ( RING_API_ISLIST(1) && RING_API_ISNUMBER(2) ) ) {
                        RING_API_ERROR(RING_API_BADPARATYPE);
                        return;
                }
        // リスト項目の複製
                pList = RING_API_GETLIST(1);
                nSize = ring_list_getsize(pList);
                nTimes = (int) RING_API_GETNUMBER(2);
                if (nTimes < 1) {
                        RING_API_ERROR("Error: The second parameter must be >= 1 \n");
                        return;
                }
                for(x = 1 ; x <= nTimes ; x++)
                        for(y = 1 ; y <= nSize ; y++)
                                if ( ring_list_isdouble(pList,y) )
                                        ring_list_adddouble(pList,
                                                ring_list_getdouble(pList,y));
        // 処理結果を返します
                RING_API_RETLIST(pList);
}

関数を新規登録します

ring_vm_funcregister("replicatelist",ring_replicatelist);

ファイル test.ring の内容

? "Loading Library"
load "mylib.ring"

? "Calling a C Function"
myfunction()

? "Sum Two Numbers (3,5)"
? SumTwoNumbers(3,5)

? "Say Hello"
SayHello("Mahmoud")

? "Sum List contains numbers from 1 to 10"
aList = 1:10
? SumList(aList)

? "Increment List Items"
? inclist(aList,10)

? "Filter List Items (Items > 15)"
? filterlist(aList,15)

aList = 1:3
? "Replicate list (1:3) three times then print the items (We expect 12 items)"
? replicatelist(aList,3)

関数のテスト

ring test.ring

実行結果

Loading Library
Calling a C Function
Hello, World!
Sum Two Numbers (3,5)
8
Say Hello
Hello Mahmoud
Sum List contains numbers from 1 to 10
55
Increment List Items
11
12
13
14
15
16
17
18
19
20


Filter List Items (Items > 15)
16
17
18
19
20

Replicate list (1:3) three times then print the items (We expect 12 items)
1
2
3
1
2
3
1
2
3
1
2
3

リストの生成

サンプル : ring/extensions/tutorial/generatelist

この拡張機能ではリストの新規作成とリストへ項目を追加する C 関数の作成方法です。

これは replicatelist 拡張機能の更新版です : ring/extensions/tutorial/replicatelist フォルダ

ファイル mylib.c を変更します

RING_FUNC(ring_generatelist)
{
        List *pList;
        int x,nSize;
        // 引数の個数を検査します
                if (RING_API_PARACOUNT != 1) {
                        RING_API_ERROR(RING_API_MISS1PARA);
                        return;
                }
        // 引数の型を検査します
                if ( ! RING_API_ISNUMBER(1) ) {
                        RING_API_ERROR(RING_API_BADPARATYPE);
                        return;
                }
        // リストを作成します
                pList = RING_API_NEWLIST;
        // リスト項目の生成
                nSize = (int) RING_API_GETNUMBER(1);
                if (nSize < 1) {
                        RING_API_ERROR("Error: The list size must be >= 1 \n");
                        return;
                }
                for(x = 1 ; x <= nSize ; x++)
                        ring_list_adddouble(pList,(double) x);
        // 処理結果を返します
                RING_API_RETLIST(pList);
}

関数を新規登録します

ring_vm_funcregister("generatelist",ring_generatelist);

ファイル test.ring の内容

? "Loading Library"
load "mylib.ring"

? "Calling a C Function"
myfunction()

? "Sum Two Numbers (3,5)"
? SumTwoNumbers(3,5)

? "Say Hello"
SayHello("Mahmoud")

? "Sum List contains numbers from 1 to 10"
aList = 1:10
? SumList(aList)

? "Increment List Items"
? inclist(aList,10)

? "Filter List Items (Items > 15)"
? filterlist(aList,15)

aList = 1:3
? "Replicate list (1:3) three times then print the items (We expect 12 items)"
? replicatelist(aList,3)

? "Create list contains 5 items using C code"
aList = GenerateList(5)
? aList

関数のテスト

ring test.ring

実行結果

Loading Library
Calling a C Function
Hello, World!
Sum Two Numbers (3,5)
8
Say Hello
Hello Mahmoud
Sum List contains numbers from 1 to 10
55
Increment List Items
11
12
13
14
15
16
17
18
19
20


Filter List Items (Items > 15)
16
17
18
19
20

Replicate list (1:3) three times then print the items (We expect 12 items)
1
2
3
1
2
3
1
2
3
1
2
3

Create list contains 5 items using C code
1
2
3
4
5

リストの表示

サンプル : ring/extensions/tutorial/displaylist

この拡張機能では多重リストも対象としたリストの全項目を表示する C 関数の作成方法です。

ファイル mylib.c を変更します

void mylib_displaylist(List *pList);

RING_FUNC(ring_displaylist)
{
        List *pList;
        // 引数の個数を検査します
                if (RING_API_PARACOUNT != 1) {
                        RING_API_ERROR(RING_API_MISS1PARA);
                        return;
                }
        // 引数の型を検査します
                if ( ! RING_API_ISLIST(1) ) {
                        RING_API_ERROR(RING_API_BADPARATYPE);
                        return;
                }
        // リストの取得
                pList = RING_API_GETLIST(1);
        // 多重リストも対象としたリスト項目の表示
                mylib_displaylist(pList);
}

void mylib_displaylist(List *pList) {
        int x;
        for (x=1; x <= ring_list_getsize(pList); x++) {
                if ( ring_list_isdouble(pList,x) ) {
                        printf("Number : %f \n", ring_list_getdouble(pList,x) ) ;
                } else if ( ring_list_isstring(pList,x) ) {
                        printf("String : %s \n", ring_list_getstring(pList,x) ) ;
                } else if ( ring_list_islist(pList,x) ) {
                        printf("Sub List..\n");
                        mylib_displaylist( ring_list_getlist(pList,x) );
                }
        }
}

関数を新規登録します

ring_vm_funcregister("displaylist",ring_displaylist);

ファイル test.ring の内容

load "stdlib.ring"

? "Loading Library"
load "mylib.ring"

? "Calling a C Function"
myfunction()

? "Sum Two Numbers (3,5)"
? SumTwoNumbers(3,5)

? "Say Hello"
SayHello("Mahmoud")

? "Sum List contains numbers from 1 to 10"
aList = 1:10
? SumList(aList)

? "Increment List Items"
? inclist(aList,10)

? "Filter List Items (Items > 15)"
? filterlist(aList,15)

aList = 1:3
? "Replicate list (1:3) three times then print the items (We expect 12 items)"
? replicatelist(aList,3)

? "Create list contains 5 items using C code"
aList = GenerateList(5)
? aList

? "Create List (3,2)"
aList = newList(3,2)
aList[1][1] = "R 1 C 1"
aList[1][2] = "R 1 C 2"
aList[2][1] = "R 2 C 1"
aList[2][2] = "R 2 C 2"
aList[3][1] = "R 3 C 1"
aList[3][2] = "R 3 C 2"
? "Print the List using Ring"
? aList
? "Print the List by calling C Code"
displayList(aList)

関数のテスト

ring test.ring

実行結果

Loading Library
Calling a C Function
Hello, World!
Sum Two Numbers (3,5)
8
Say Hello
Hello Mahmoud
Sum List contains numbers from 1 to 10
55
Increment List Items
11
12
13
14
15
16
17
18
19
20


Filter List Items (Items > 15)
16
17
18
19
20

Replicate list (1:3) three times then print the items (We expect 12 items)
1
2
3
1
2
3
1
2
3
1
2
3

Create list contains 5 items using C code
1
2
3
4
5

Create List (3,2)
Print the List using Ring
R 1 C 1
R 1 C 2
R 2 C 1
R 2 C 2
R 3 C 1
R 3 C 2

Print the List by calling C Code
Sub List..
String : R 1 C 1
String : R 1 C 2
Sub List..
String : R 2 C 1
String : R 2 C 2
Sub List..
String : R 3 C 1
String : R 3 C 2

テーブルの更新

サンプル : ring/extensions/tutorial/updatetable

この拡張機能では行列から構成されるテーブルの更新を行う C 関数の作成方法です。

ファイル mylib.c を変更します

RING_FUNC(ring_updatetable)
{
        List *pList, *pRow;
        int nRow,nCol;
        // 引数の個数を検査します
                if (RING_API_PARACOUNT != 2) {
                        RING_API_ERROR(RING_API_MISS2PARA);
                        return;
                }
        // 引数の型を検査します
                if ( ! ( RING_API_ISLIST(1) && RING_API_ISNUMBER(2) ) ) {
                        RING_API_ERROR(RING_API_BADPARATYPE);
                        return;
                }
        // リストの取得 (テーブル表記)
                pList = RING_API_GETLIST(1);
        // テーブルの行列更新
        for (nRow = 1 ; nRow <= ring_list_getsize(pList) ; nRow++ ) {
                if ( ring_list_islist(pList,nRow) ) {
                pRow = ring_list_getlist(pList,nRow);
                for (nCol = 1 ; nCol <= ring_list_getsize(pRow) ; nCol++ ) {
                        if ( ring_list_isdouble(pRow,nCol) ) {
                                ring_list_setdouble(pRow,nCol,RING_API_GETNUMBER(2));
                        } else {
                                RING_API_ERROR("Error : We expect numbers!\n");
                                return ;
                        }
                }
                } else {
                        RING_API_ERROR("Error : The parameter is not a table! \n");
                        return ;
                }
        }
}

関数を新規登録します

ring_vm_funcregister("updatetable",ring_updatetable);

ファイル test.ring の内容

load "stdlib.ring"

? "Loading Library"
load "mylib.ring"

? "Calling a C Function"
myfunction()

? "Sum Two Numbers (3,5)"
? SumTwoNumbers(3,5)

? "Say Hello"
SayHello("Mahmoud")

? "Sum List contains numbers from 1 to 10"
aList = 1:10
? SumList(aList)

? "Increment List Items"
? inclist(aList,10)

? "Filter List Items (Items > 15)"
? filterlist(aList,15)

aList = 1:3
? "Replicate list (1:3) three times then print the items (We expect 12 items)"
? replicatelist(aList,3)

? "Create list contains 5 items using C code"
aList = GenerateList(5)
? aList

? "Create List (3,2)"
aList = newList(3,2)
aList[1][1] = "R 1 C 1"
aList[1][2] = "R 1 C 2"
aList[2][1] = "R 2 C 1"
aList[2][2] = "R 2 C 2"
aList[3][1] = "R 3 C 1"
aList[3][2] = "R 3 C 2"
? "Print the List using Ring"
? aList
? "Print the List by calling C Code"
displayList(aList)
? ""

? "Create List (2,2)"
aList = newList(2,2)
? "Update the list using C code - set all cells to 10"
UpdateTable(aList,10)
? "aList[1][1] : " + aList[1][1]
? "aList[1][2] : " + aList[1][2]
? "aList[2][1] : " + aList[2][1]
? "aList[2][2] : " + aList[2][2]

関数のテスト

ring test.ring

実行結果

Loading Library
Calling a C Function
Hello, World!
Sum Two Numbers (3,5)
8
Say Hello
Hello Mahmoud
Sum List contains numbers from 1 to 10
55
Increment List Items
11
12
13
14
15
16
17
18
19
20


Filter List Items (Items > 15)
16
17
18
19
20

Replicate list (1:3) three times then print the items (We expect 12 items)
1
2
3
1
2
3
1
2
3
1
2
3

Create list contains 5 items using C code
1
2
3
4
5

Create List (3,2)
Print the List using Ring
R 1 C 1
R 1 C 2
R 2 C 1
R 2 C 2
R 3 C 1
R 3 C 2

Print the List by calling C Code
Sub List..
String : R 1 C 1
String : R 1 C 2
Sub List..
String : R 2 C 1
String : R 2 C 2
Sub List..
String : R 3 C 1
String : R 3 C 2

Create List (2,2)
Update the list using C code - set all cells to 10
aList[1][1] : 10
aList[1][2] : 10
aList[2][1] : 10
aList[2][2] : 10

テーブルの作成

サンプル : ring/extensions/tutorial/createtable

この拡張機能では行列から構成されるテーブルの生成を行う C 関数の作成方法です。

ファイル mylib.c を変更します

RING_FUNC(ring_createtable)
{
        List *pList, *pRow;
        int x,y,nRows,nCols;
        // 引数の個数を検査します
                if (RING_API_PARACOUNT != 2) {
                        RING_API_ERROR(RING_API_MISS2PARA);
                        return;
                }
        // 引数の型を検査します
                if ( ! ( RING_API_ISNUMBER(1) && RING_API_ISNUMBER(2) ) ) {
                        RING_API_ERROR(RING_API_BADPARATYPE);
                        return;
                }
        // リストを作成します
                pList = RING_API_NEWLIST;
        // テーブルの項目を作成します
                nRows = (int) RING_API_GETNUMBER(1);
                nCols = (int) RING_API_GETNUMBER(2);
                if ( (nRows < 1) || (nCols < 1) ) {
                RING_API_ERROR("Error: The table rows and columns must be >= 1 \n");
                return;
                }
                for(x = 1 ; x <= nRows ; x++) {
                        pRow = ring_list_newlist(pList);
                        for(y = 1 ; y <= nCols ; y++)
                                ring_list_adddouble(pRow,0.0);
                }
        // 処理結果を返します
                RING_API_RETLIST(pList);
}

関数を新規登録します

ring_vm_funcregister("createtable",ring_createtable);

ファイル test.ring の内容

load "stdlib.ring"

? "Loading Library"
load "mylib.ring"

? "Calling a C Function"
myfunction()

? "Sum Two Numbers (3,5)"
? SumTwoNumbers(3,5)

? "Say Hello"
SayHello("Mahmoud")

? "Sum List contains numbers from 1 to 10"
aList = 1:10
? SumList(aList)

? "Increment List Items"
? inclist(aList,10)

? "Filter List Items (Items > 15)"
? filterlist(aList,15)

aList = 1:3
? "Replicate list (1:3) three times then print the items (We expect 12 items)"
? replicatelist(aList,3)

? "Create list contains 5 items using C code"
aList = GenerateList(5)
? aList

? "Create List (3,2)"
aList = newList(3,2)
aList[1][1] = "R 1 C 1"
aList[1][2] = "R 1 C 2"
aList[2][1] = "R 2 C 1"
aList[2][2] = "R 2 C 2"
aList[3][1] = "R 3 C 1"
aList[3][2] = "R 3 C 2"
? "Print the List using Ring"
? aList
? "Print the List by calling C Code"
displayList(aList)
? ""

? "Create List (2,2)"
aList = newList(2,2)
? "Update the list using C code - set all cells to 10"
UpdateTable(aList,10)
? "aList[1][1] : " + aList[1][1]
? "aList[1][2] : " + aList[1][2]
? "aList[2][1] : " + aList[2][1]
? "aList[2][2] : " + aList[2][2]
? ""

? "Create List (3,3) using C code"
aList = CreateTable(3,3)
? "aList[1][1] : " + aList[1][1]
? "aList[1][2] : " + aList[1][2]
? "aList[1][3] : " + aList[1][3]
? "aList[2][1] : " + aList[2][1]
? "aList[2][2] : " + aList[2][2]
? "aList[2][3] : " + aList[2][3]
? "aList[3][1] : " + aList[3][1]
? "aList[3][2] : " + aList[3][2]
? "aList[3][3] : " + aList[3][3]

関数のテスト

ring test.ring

実行結果

Loading Library
Calling a C Function
Hello, World!
Sum Two Numbers (3,5)
8
Say Hello
Hello Mahmoud
Sum List contains numbers from 1 to 10
55
Increment List Items
11
12
13
14
15
16
17
18
19
20


Filter List Items (Items > 15)
16
17
18
19
20

Replicate list (1:3) three times then print the items (We expect 12 items)
1
2
3
1
2
3
1
2
3
1
2
3

Create list contains 5 items using C code
1
2
3
4
5

Create List (3,2)
Print the List using Ring
R 1 C 1
R 1 C 2
R 2 C 1
R 2 C 2
R 3 C 1
R 3 C 2

Print the List by calling C Code
Sub List..
String : R 1 C 1
String : R 1 C 2
Sub List..
String : R 2 C 1
String : R 2 C 2
Sub List..
String : R 3 C 1
String : R 3 C 2

Create List (2,2)
Update the list using C code - set all cells to 10
aList[1][1] : 10
aList[1][2] : 10
aList[2][1] : 10
aList[2][2] : 10

Create List (3,3) using C code
aList[1][1] : 0
aList[1][2] : 0
aList[1][3] : 0
aList[2][1] : 0
aList[2][2] : 0
aList[2][3] : 0
aList[3][1] : 0
aList[3][2] : 0
aList[3][3] : 0