rewrite dynlib management and addinter function
[scilab.git] / scilab / modules / dynamic_link / src / cpp / addinter.cpp
1 /*
2  * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  * Copyright (C) INRIA/ENPC
4  * Copyright (C) 2008 - INRIA - Allan CORNET
5  * 
6  * This file must be used under the terms of the CeCILL.
7  * This source file is licensed as described in the file COPYING, which
8  * you should have received as part of this distribution.  The terms
9  * are also available at    
10  * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
11  *
12  */
13
14 /*-----------------------------------------------------------------------------------*/
15 #include "configvariable.hxx"
16
17 extern "C"
18 {
19 #include <string.h> 
20 #include <stdio.h>
21 #include <stdlib.h>
22
23 #include "core_math.h"
24 #include "dynamic_link.h"
25 #include "men_Sutils.h"
26 #include "addinter.h" 
27
28 #include "do_error_number.h"
29 #include "stack-c.h"
30 #include "MALLOC.h" /* MALLOC */
31 #include "sciprint.h"
32 #include "Funtab.h"
33 #include "sci_warning.h"
34 #include "GetenvB.h"
35 #include "localization.h"
36 #include "Scierror.h"
37 #ifdef _MSC_VER
38 #include "ExceptionMessage.h"
39 #endif
40 }
41 /* size of interface name */
42 /* scilab limitation to nlgh characters (24)*/
43 #define INTERFSIZE nlgh + 1 
44 /*-----------------------------------------------------------------------------------*/
45 typedef struct 
46 {
47         char name[INTERFSIZE]; /** name of interface **/
48         void (*func)();        /** entrypoint for the interface **/
49         int Nshared; /** id of the shared library **/
50         BOOL ok;    /** flag set to TRUE if entrypoint can be used **/
51 } InterfaceElement;
52 /*-----------------------------------------------------------------------------------*/
53 InterfaceElement *DynInterf = NULL;
54 static int MaxInterfaces = MAXDYNINTERF;
55 /*-----------------------------------------------------------------------------------*/
56 static int LastInterf = 0;
57 static void initializeInterfaces(void);
58 static BOOL reallocDynInterf(void);
59 /*-----------------------------------------------------------------------------------*/
60 int AddInterfaceToScilab(wchar_t* _pwstDynamicLibraryName, wchar_t* _pwstModuleName, wchar_t** _pwstEntryPointName, int _iEntryPointSize)
61 {
62         int iLibID = -1; /* Id of library */
63         int iErr = 0;
64         
65         /** Try to unlink the interface if it was previously linked **/
66     ConfigVariable::EntryPointStr* pEP = ConfigVariable::getEntryPoint(_pwstModuleName);
67     if(pEP)
68     {//entry point already linked, so remove it before add it
69         ConfigVariable::removeDynamicLibrary(pEP->iLibIndex);
70     }
71
72         /* link then search  */ 
73         /* Haven't been able to find the symbol. Try C symbol */
74     iLibID =  scilabLink(iLibID, _pwstDynamicLibraryName, &_pwstModuleName, 1, FALSE, &iErr);
75     if(iErr)
76         {
77         /* Trying with the fortran symbol */
78         iLibID =  scilabLink(iLibID, _pwstDynamicLibraryName, &_pwstModuleName, 1, TRUE, &iErr);
79         if(iErr)
80         {
81             return iErr;
82         }
83     }
84
85     pEP = ConfigVariable::getEntryPoint(_pwstModuleName);
86     if(pEP == NULL)
87     {//
88         return -1;
89     }
90
91     for(int i = 0 ; i < _iEntryPointSize ; i++)
92     {
93         pEP->functionPtr(_pwstEntryPointName[i]);
94     }
95         return 0;
96 }
97 /*-----------------------------------------------------------------------------------*/
98 static void initializeInterfaces(void)
99 {
100         static int first_entry_interfaces = 0;
101
102         if ( first_entry_interfaces == 0) 
103         {
104                 if (DynInterf == NULL)
105                 {
106                         DynInterf = (InterfaceElement*)MALLOC(sizeof(InterfaceElement)*MaxInterfaces);
107                         if (DynInterf)
108                         {
109                                 int i = 0;
110                                 for ( i= 0 ; i < MaxInterfaces ; i++) 
111                                 {
112                                         strcpy(DynInterf[i].name,"");
113                                         DynInterf[i].func = NULL;
114
115                                         DynInterf[i].Nshared = -1;
116                                         DynInterf[i].ok = FALSE;
117                                 }
118                         }
119                 }
120                 first_entry_interfaces++;
121         }
122 }
123 /*-----------------------------------------------------------------------------------*/
124 /*********************************
125 * used in unlinksharedlib(i) 
126 *********************************/
127 void RemoveInterf(int id)
128 {
129         int i = 0;
130         for ( i = 0 ; i < LastInterf ; i++ ) 
131         {
132                 if ( DynInterf[i].Nshared == id ) 
133                 {
134                         DynInterf[i].ok = FALSE;
135                         break;
136                 }
137         }
138 }
139 /*-----------------------------------------------------------------------------------*/
140 /************************************************
141 * Used when one want to call a function added 
142 * with addinterf the dynamic interface number 
143 * is given by *k - (DynInterfStart+1)
144 ************************************************/
145 void C2F(userlk)(int *k)
146 {
147         int k1 = *k - (DynInterfStart+1) ;
148
149         int imes = 9999;
150         if ( k1 >= LastInterf || k1 < 0 ) 
151         {
152                 if (getWarningMode()) 
153                 {
154                         Scierror(999,_("Error: Not a valid internal routine number %d.\n"), *k);
155                 }
156                 SciError(imes);
157                 return;
158         }
159
160         if ( DynInterf[k1].ok == 1 ) 
161         {
162 #ifdef _MSC_VER
163 #ifndef _DEBUG
164                 _try
165                 {
166                         (*DynInterf[k1].func)();
167                 }
168                 _except (EXCEPTION_EXECUTE_HANDLER)
169                 {
170                         ExceptionMessage(GetExceptionCode(),DynInterf[k1].name);
171                 }
172 #else
173                 (*DynInterf[k1].func)();
174 #endif
175 #else
176                 (*DynInterf[k1].func)();
177 #endif
178         }
179         else 
180         {
181                 if (getWarningMode()) sciprint(_("Interface %s not linked.\n"),DynInterf[k1].name);
182                 SciError(imes);
183                 return;
184         }
185 }
186 /*-----------------------------------------------------------------------------------*/
187 static BOOL reallocDynInterf(void)
188 {
189         /* increase table of interfaces by 2 */
190         int newMaxInterfaces = MaxInterfaces * 2;
191
192         if (newMaxInterfaces < ENTRYMAX)
193         {
194                 if (DynInterf)
195                 {
196                         int i = 0;
197                         InterfaceElement *newDynInterf = NULL;
198
199                         newDynInterf = (InterfaceElement*)REALLOC(DynInterf,sizeof(InterfaceElement)*newMaxInterfaces);
200                         if (newDynInterf == NULL) return FALSE;
201
202                         DynInterf = newDynInterf;
203
204                         for ( i= MaxInterfaces ; i < newMaxInterfaces ; i++) 
205                         {
206                                 strcpy(DynInterf[i].name,"");
207                                 DynInterf[i].func = NULL;
208                                 DynInterf[i].Nshared = -1;
209                                 DynInterf[i].ok = FALSE;
210                         }
211                         MaxInterfaces = newMaxInterfaces;
212                         return TRUE;
213                 }
214                 else return FALSE;
215         }
216         return FALSE;
217 }
218 /*-----------------------------------------------------------------------------------*/