[cleanup] stackxxx.h removed
[scilab.git] / scilab / modules / dynamic_link / src / cpp / dynamic_link.cpp
1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) INRIA/ENPC
4 * Copyright (C) DIGITEO - 2011 - 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
16 #include "configvariable.hxx"
17
18 extern "C"
19 {
20 #include <string.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include "dynamic_link.h"
24 #include "men_Sutils.h"
25 #include "sci_malloc.h" /* MALLOC */
26 #include "configvariable_interface.h"
27 #include "sciprint.h"
28 #include "addinter.h"
29 #include "localization.h"
30 #include "Scierror.h"
31 #include "FileExist.h"
32 #include "ilib_verbose.h"
33
34 #ifdef _MSC_VER
35 #include "getenvc.h"
36 #include "dllinfo.h"
37 #endif
38
39 #include "getshortpathname.h"
40 #include "BOOL.h"
41 #include "charEncoding.h"
42 }
43
44 static void Underscores(BOOL _bFortran, wchar_t* _pwstEntryPointName, wchar_t* _pwstTrailingName);
45
46 typedef void (*function) ();
47
48
49 int scilabLink(int _iLibID, wchar_t* _pwstLibraryName, wchar_t** _pwstEntryPointName, int _iEntryPointSize, BOOL _bFortran , int *_piErr)
50 {
51     int iLibID = -1;
52
53     if (_iLibID == -1)
54     {
55         iLibID = Sci_dlopen(_pwstLibraryName);
56     }
57     else
58     {
59         iLibID = _iLibID;
60     }
61
62     if (iLibID == -1)
63     {
64         if ( getWarningMode() )
65         {
66 #ifdef _MSC_VER
67             if (isDllW(_pwstLibraryName))
68             {
69 #ifdef _WIN64
70                 if (isX86DllW(_pwstLibraryName))
71                 {
72                     if (getIlibVerboseLevel() != ILIB_VERBOSE_NO_OUTPUT)
73                     {
74                         sciprint(_("%s: can not to load a x86 dll in a x64 environment.\n" ), "link");
75                     }
76                     SetLastError(ERROR_DLL_INIT_FAILED);
77                 }
78 #else
79                 if (isX64DllW(_pwstLibraryName))
80                 {
81                     if (getIlibVerboseLevel() != ILIB_VERBOSE_NO_OUTPUT)
82                     {
83                         sciprint(_("%s: can not load a x64 dll in a x86 environment.\n" ), "link");
84                     }
85                     SetLastError(ERROR_DLL_INIT_FAILED);
86                 }
87 #endif
88             }
89             else
90             {
91                 wchar_t* pwstPathSearch = searchEnvW(_pwstLibraryName, L"PATH");
92                 if (pwstPathSearch == NULL)
93                 {
94                     if (getIlibVerboseLevel() != ILIB_VERBOSE_NO_OUTPUT)
95                     {
96                         sciprint(_("%ls: The file %ls does not exist in PATH environment.\n" ), L"link", _pwstLibraryName);
97                     }
98                 }
99             }
100 #else
101             if (getIlibVerboseLevel() != ILIB_VERBOSE_NO_OUTPUT)
102             {
103                 sciprint(_("Link failed for dynamic library '%ls'.\n"), _pwstLibraryName);
104                 sciprint(_("An error occurred: %s\n"), GetLastDynLibError());
105             }
106 #endif
107         }
108         *_piErr = -1;
109         return iLibID;
110     }
111
112     if ( (_iLibID == -1) && (getIlibVerboseLevel() != ILIB_VERBOSE_NO_OUTPUT))
113     {
114         sciprint(_("Shared archive loaded.\n"));
115         sciprint(_("Link done.\n"));
116     }
117
118     for (int i = 0 ; i < _iEntryPointSize ; i++)
119     {
120         *_piErr = Sci_dlsym(_pwstEntryPointName[i], iLibID, _bFortran);
121     }
122
123     return iLibID;
124 }
125 /*---------------------------------------------------------------------------*/
126 /**
127 * Underscores : deals with the trailing _
128 * in entry names
129 */
130 static void Underscores(BOOL _bFortran, wchar_t* _pwstEntryPointName, wchar_t* _pwstTrailingName)
131 {
132 #ifdef WLU1
133     *_pwstTrailingName = L'_';
134     _pwstTrailingName++;
135 #endif
136     wcscpy(_pwstTrailingName, _pwstEntryPointName);
137 #ifdef WTU
138     if (_bFortran)
139     {
140         wcscat(_pwstTrailingName, L"_");
141     }
142 #endif
143     return;
144 }
145 /*---------------------------------------------------------------------------*/
146 int Sci_dlclose(DynLibHandle _hLib)
147 {
148     return FreeDynLibrary(_hLib);
149 }
150 /*---------------------------------------------------------------------------*/
151 int Sci_dlopen(wchar_t* _pwstDynLibPath)
152 {
153     static DynLibHandle hLib = NULL;
154     int i = 0;
155
156 #ifdef _MSC_VER
157     {
158         hLib = LoadDynLibraryW(_pwstDynLibPath);
159     }
160 #else
161     {
162         char* pstDynLibPath = wide_string_to_UTF8(_pwstDynLibPath);
163         hLib = LoadDynLibrary (pstDynLibPath);
164         FREE(pstDynLibPath);
165     }
166 #endif
167
168     if (hLib == NULL)
169     {
170         return -1 ; /* the shared archive was not loaded. */
171     }
172
173     ConfigVariable::DynamicLibraryStr* pDL = ConfigVariable::getNewDynamicLibraryStr();
174     ConfigVariable::setLibraryName(pDL, _pwstDynLibPath);
175     pDL->hLib = hLib;
176
177
178     return ConfigVariable::addDynamicLibrary(pDL);
179 }
180 /*---------------------------------------------------------------------------*/
181 int Sci_dlsym(wchar_t* _pwstEntryPointName, int _iLibID, BOOL _bFortran)
182 {
183     DynLibHandle hDynLib = NULL;
184     ConfigVariable::EntryPointStr* pEP = ConfigVariable::getNewEntryPointStr();
185     //+3 : 1 for '\0', 1 for prefix _, 1 for suffix _
186     wchar_t* pwstEntryPointName = (wchar_t*)MALLOC(sizeof(wchar_t) * (wcslen(_pwstEntryPointName) + 3));
187     memset(pwstEntryPointName, 0x00, (wcslen(_pwstEntryPointName) + 3));
188
189     Underscores(_bFortran, _pwstEntryPointName, pwstEntryPointName);
190
191
192     if (_iLibID < 0 || ConfigVariable::isDynamicLibrary(_iLibID) == false)
193     {
194         //no valid library at this ID
195         return -3;
196     }
197
198     /** entry was previously loaded **/
199     if (ConfigVariable::getEntryPoint(_pwstEntryPointName, _iLibID) != NULL)
200     {
201         sciprint(_("Entry name %ls.\n"), _pwstEntryPointName);
202         return -4;
203     }
204
205     pEP->iLibIndex = _iLibID;
206     hDynLib = (DynLibHandle)  ConfigVariable::getDynamicLibrary(_iLibID)->hLib;
207 #ifdef _MCS_VER
208     pEP->functionPtr = (function) GetDynLibFuncPtrW(hDynLib, pwstEntryPointName);
209 #else
210     char* pstEntryPointName = wide_string_to_UTF8(pwstEntryPointName);
211     pEP->functionPtr = (function) GetDynLibFuncPtr(hDynLib, pstEntryPointName);
212     FREE(pstEntryPointName);
213 #endif
214     if (pEP->functionPtr == NULL)
215     {
216         if (getIlibVerboseLevel() != ILIB_VERBOSE_NO_OUTPUT)
217         {
218             sciprint(_("%ls is not an entry point.\n"), _pwstEntryPointName);
219         }
220         return -5;
221     }
222
223
224     if (0 /*debug mode*/)
225     {
226         sciprint(_("Linking %ls.\n"), _pwstEntryPointName);
227     }
228
229     ConfigVariable::setEntryPointName(pEP, _pwstEntryPointName);
230     ConfigVariable::addEntryPoint(pEP);
231     FREE(pwstEntryPointName);
232     return 0;
233 }
234 /*---------------------------------------------------------------------------*/