Definition of the links between Scol language and DLL functions » History » Version 2
ModularMix, 10/14/2011 04:52 PM
1 | 1 | ModularMix | h1. Definition of the links between Scol language and DLL functions |
---|---|---|---|
2 | |||
3 | 2 | ModularMix | This article shows the possibility to add new functions to Scol language using the integration of plugins written in C language. |
4 | 1 | ModularMix | |
5 | 2 | ModularMix | h2. Creation of a simple function "HelloWorld" |
6 | 1 | ModularMix | |
7 | 2 | ModularMix | We will create our first C function which we will be able to call from Scol language. |
8 | This function will allow to display a log message ("Hello World") in the Scol console. |
||
9 | The first thing to do right here is to write the C function. It's important to take a look at the function signature, because it takes a *machine* object as a parameter and returns an integer. |
||
10 | 1 | ModularMix | |
11 | 2 | ModularMix | It's also important to notice *MMechostr* function from the Scol API. This method takes as parameters the log level (*MSKFOO*, *MSKRUNTIME*, *MSKWARNING*, *MSKTRACE* or *MSKDEBUG*) and the message to log. |
12 | |||
13 | Finally, we have to notice *MMset* function which purpose is to set a value for the first element of Scol stack (in our case, an integer which value is 0), this one corresponding to *the return value of the Scol function*, accordingly to the expected Scol prototype (*fun [ ] I*, a function without any parameter and returning an integer). |
||
14 | <pre> |
||
15 | 1 | ModularMix | /*! @ingroup group1 |
16 | * \brief _HelloWorld : Log a "Hello World" message in the console |
||
17 | * |
||
18 | * <b>Prototype:</b> fun [] I |
||
19 | * |
||
20 | * \return I : 0 in all cases. |
||
21 | **/ |
||
22 | int _HelloWorld(mmachine m) |
||
23 | { |
||
24 | // Show the message |
||
25 | MMechostr(MSKRUNTIME, "Hello World!"); |
||
26 | |||
27 | // Scol return value. |
||
28 | MMset(m,0,0); |
||
29 | |||
30 | return 0; |
||
31 | } |
||
32 | 2 | ModularMix | </pre> |
33 | |||
34 | h2. Binding between C and Scol |
||
35 | |||
36 | To be able to call the function *HelloWorld* directly from Scol language, we have to register it. The function from the Scol API enabling it is *PKhardpak*. |
||
37 | <pre> |
||
38 | /*! |
||
39 | * \brief Load the template functions |
||
40 | * |
||
41 | * \param mmachine : scol machine structure |
||
42 | * |
||
43 | * \return int : 0 if succes, error code otherwise |
||
44 | **/ |
||
45 | int LoadTemplate(mmachine m) |
||
46 | { |
||
47 | int k; |
||
48 | |||
49 | // Load package |
||
50 | k = PKhardpak(m, "TemplateEngine", NbTplPKG, TplName, TplFunc, TplNArg, TplType); |
||
51 | return k; |
||
52 | } |
||
53 | </pre> |
||
54 | |||
55 | The parameters of the function are the following : |
||
56 | * *NbTplPKG* : the number of functions we have to export to Scol (the different arrays described below must have as many values as this number) |
||
57 | * *TplName* : an array containing the name of the functions as they will be called in a Scol source code |
||
58 | * *TplFunc* : an array of pointers to C functions, corresponding to the bindings of Scol functions to their equivalent in C language |
||
59 | * *TplNArg* : an array of integers representing the number of arguments expected for each function |
||
60 | * *TplType* : an array of strings containing the Scol prototypes for each function |
||
61 | |||
62 | *WARNING* : If several functions are being exported, we have to make sure that for all the arrays, the functions are in the same order. |
||
63 | |||
64 | Now, we can inject the following source code just before calling *PKhardpak*. A good habit is to use the same name for the Scol function and for the C function because is simplifies the edition of the documentation and the revision of the source code. |
||
65 | <pre> |
||
66 | //! Nb of Scol functions or types |
||
67 | #define NbTplPKG 1 |
||
68 | |||
69 | /*! |
||
70 | * Scol function names |
||
71 | **/ |
||
72 | char* TplName[NbTplPKG] = |
||
73 | { |
||
74 | "_HelloWorld" |
||
75 | }; |
||
76 | |||
77 | /*! |
||
78 | * Pointers to C functions that manipulate the VM for each scol function previously defined |
||
79 | **/ |
||
80 | int (*TplFunc[NbTplPKG])(mmachine m)= |
||
81 | { |
||
82 | _HelloWorld |
||
83 | }; |
||
84 | |||
85 | /*! |
||
86 | * Nb of arguments of each scol function |
||
87 | **/ |
||
88 | int TplNArg[NbTplPKG]= |
||
89 | { |
||
90 | 0 |
||
91 | }; |
||
92 | |||
93 | /*! |
||
94 | * Prototypes of the scol functions |
||
95 | **/ |
||
96 | char* TplType[NbTplPKG]= |
||
97 | { |
||
98 | "fun [] I" // _HelloWorld |
||
99 | }; |
||
100 | </pre> |
||
101 | |||
102 | |||
103 | To finish the binding of the C function, all we need to do is to call the function named *LoadTemplate* when the plugin is being initialized, that is to say in *SCOLloadTemplate* function. The content of this one should now be the following : |
||
104 | <pre> |
||
105 | /*! |
||
106 | * \brief Starting point of the DLL |
||
107 | **/ |
||
108 | extern "C" __declspec (dllexport) |
||
109 | int SCOLloadTemplate(mmachine m, cbmachine w) |
||
110 | { |
||
111 | SCOLinitplugin(w); |
||
112 | // Get Scol window handle (for message callback) |
||
113 | HScol = (HWND)SCgetExtra("hscol"); |
||
114 | |||
115 | // Display debug message |
||
116 | MMechostr(MSKDEBUG,"Loading Template DLL ...\n"); |
||
117 | return LoadTemplate(m); |
||
118 | } |
||
119 | </pre> |
||
120 | |||
121 | After that, it's now possible to compile the project and move the DLL file into the *plugins* directory of the Scol Voyager installation folder, which is usually *C:\Program Files (x86)\Scol Voyager*. |
||
122 | |||
123 | h2. Use of the new function in Scol language |
||
124 | |||
125 | We will now create a new Scol source code, in which we will call our function previously created. |
||
126 | Let's create a new file called *template.pkg* in the Scol Voyager user partition, which is usually located in *My Documents\Scol Voyager\Partition_LocalUsr*. The file will only contain a main function calling our *HelloWorld* method : |
||
127 | <pre> |
||
128 | /*! \brief Sample main function that log a "Hello World" message. |
||
129 | * |
||
130 | * <b>Prototype:</b> fun [] I |
||
131 | * |
||
132 | * \return I : 0 |
||
133 | **/ |
||
134 | fun main()= |
||
135 | _HelloWorld;; |
||
136 | </pre> |
||
137 | |||
138 | Let's create another file in our user partition, named *HelloWorld.scol*. This program will load the package *template.pkg* that we have just created, and run its *main* function : |
||
139 | <pre> |
||
140 | _load "template.pkg" |
||
141 | main |
||
142 | </pre> |
||
143 | |||
144 | Now, we can run the program *HelloWorld.scol* and notice that the log message we've defined in the C function is displayed in Scol console. |