@@ -936,7 +936,82 @@ static bool __split_binding(MCStringRef& x_string, codepoint_t p_char, MCStringR
936936 return true ;
937937}
938938
939- static bool MCScriptResolveForeignFunctionBinding (MCScriptForeignHandlerDefinition *p_handler, ffi_abi& r_abi, bool p_throw, bool & r_bound)
939+ static bool MCScriptPlatformLoadSharedLibrary (MCStringRef p_path, void *& r_handle)
940+ {
941+ #if defined(_WIN32)
942+ HMODULE t_module;
943+ MCAutoStringRefAsWString t_library_wstr;
944+ if (!t_library_wstr.Lock (p_path))
945+ return false ;
946+ t_module = LoadLibraryW (*t_library_wstr);
947+ if (t_module == NULL )
948+ return false ;
949+ r_handle = (void *)t_module;
950+ #else
951+ MCAutoStringRefAsUTF8String t_utf8_library;
952+ if (!t_utf8_library.Lock (p_path))
953+ return false ;
954+ void *t_module;
955+ t_module = dlopen (*t_utf8_library, RTLD_LAZY);
956+ if (t_module == NULL )
957+ return false ;
958+ r_handle = (void *)t_module;
959+ #endif
960+ return true ;
961+ }
962+
963+ static bool MCScriptPlatformLoadSharedLibraryFunction (void *p_module, MCStringRef p_function, void *& r_pointer)
964+ {
965+ MCAutoStringRefAsCString t_function_name;
966+ if (!t_function_name.Lock (p_function))
967+ return false ;
968+
969+ void *t_pointer;
970+ #if defined(_WIN32)
971+ t_pointer = GetProcAddress (p_module, *t_function_name);
972+ #else
973+ t_pointer = dlsym (p_module, *t_function_name);
974+ #endif
975+
976+ return true ;
977+ }
978+
979+ static bool MCScriptLoadSharedLibrary (MCScriptModuleRef p_module, MCStringRef p_library, void *& r_handle)
980+ {
981+ // If there is no library name then we resolve to the executable module.
982+ if (MCStringIsEmpty (p_library))
983+ {
984+ #if defined(_WIN32)
985+ r_handle = GetModuleHandle (NULL );
986+ #elif defined(TARGET_SUBPLATFORM_ANDROID)
987+ r_handle = dlopen (" librevandroid.so" , 0 );
988+ #else
989+ r_handle = dlopen (NULL , 0 );
990+ #endif
991+ return true ;
992+ }
993+
994+ // If there is no slash in the name, we try to resolve based on the module.
995+ uindex_t t_offset;
996+ if (!MCStringFirstIndexOfChar (p_library, ' /' , 0 , kMCStringOptionCompareExact , t_offset))
997+ {
998+ MCAutoStringRef t_mapped_library;
999+ if (MCScriptResolveSharedLibrary (p_module, p_library, Out (t_mapped_library)))
1000+ {
1001+ if (MCScriptPlatformLoadSharedLibrary (*t_mapped_library, r_handle))
1002+ return true ;
1003+ }
1004+ }
1005+
1006+ // If the previous two things failed, then just try to load the library as written.
1007+ if (MCScriptPlatformLoadSharedLibrary (p_library, r_handle))
1008+ return true ;
1009+
1010+ // Oh dear - no native code library for us!
1011+ return false ;
1012+ }
1013+
1014+ static bool MCScriptResolveForeignFunctionBinding (MCScriptInstanceRef p_instance, MCScriptForeignHandlerDefinition *p_handler, ffi_abi& r_abi, bool p_throw, bool & r_bound)
9401015{
9411016 MCStringRef t_rest;
9421017 t_rest = MCValueRetain (p_handler -> binding);
@@ -979,62 +1054,21 @@ static bool MCScriptResolveForeignFunctionBinding(MCScriptForeignHandlerDefiniti
9791054 if (!MCStringIsEmpty (*t_class))
9801055 return MCErrorCreateAndThrow (kMCGenericErrorTypeInfo , " reason" , MCSTR (" class not allowed in c binding string" ), nil);
9811056
982-
983- #ifdef _WIN32
984- if (MCStringIsEmpty (*t_library))
1057+ void *t_module;
1058+ if (!MCScriptLoadSharedLibrary (MCScriptGetModuleOfInstance (p_instance), *t_library, t_module))
9851059 {
986- p_handler -> function = GetProcAddress (GetModuleHandle (NULL ), MCStringGetCString (*t_function));
987- }
988- else
989- {
990- HMODULE t_module;
991- MCAutoStringRefAsWString t_library_wstr;
992- if (!t_library_wstr.Lock (*t_library))
993- return false ;
994- t_module = LoadLibraryW (*t_library_wstr);
995- if (t_module == nil)
996- {
997- if (p_throw)
998- return MCErrorCreateAndThrow (kMCGenericErrorTypeInfo , " reason" , MCSTR (" unable to load foreign library" ), nil);
999-
1000- r_bound = false ;
1001- return true ;
1002- }
1003- p_handler -> function = GetProcAddress (t_module, MCStringGetCString (*t_function));
1004- }
1005- #else
1006- if (MCStringIsEmpty (*t_library))
1007- {
1008- void * t_self;
1009- #ifdef TARGET_SUBPLATFORM_ANDROID
1010- t_self = dlopen (" librevandroid.so" , 0 );
1011- if (t_self == NULL )
1012- {
1013- return MCErrorCreateAndThrow (kMCGenericErrorTypeInfo , " reason" , MCSTR (" could not bind to engine" ), nil);
1014- }
1015- #else
1016- t_self = dlopen (NULL , 0 );
1017- #endif
1018- p_handler -> function = dlsym (t_self, MCStringGetCString (*t_function));
1019- }
1020- else
1021- {
1022- MCAutoStringRefAsUTF8String t_utf8_library;
1023- if (!t_utf8_library.Lock (*t_library))
1024- return false ;
1025- void *t_module;
1026- t_module = dlopen (*t_utf8_library, RTLD_LAZY);
1027- if (t_module == nil)
1028- {
1029- if (p_throw)
1030- return MCErrorCreateAndThrow (kMCGenericErrorTypeInfo , " reason" , MCSTR (" unable to load foreign library" ), nil);
1031-
1032- r_bound = false ;
1033- return true ;
1034- }
1035- p_handler -> function = dlsym (t_module, MCStringGetCString (*t_function));
1060+ if (p_throw)
1061+ return MCErrorCreateAndThrow (kMCGenericErrorTypeInfo , " reason" , MCSTR (" unable to load foreign library" ), nil);
1062+
1063+ r_bound = false ;
1064+ return true ;
10361065 }
1037- #endif
1066+
1067+ void *t_pointer;
1068+ if (!MCScriptPlatformLoadSharedLibraryFunction (t_module, *t_function, t_pointer))
1069+ return false ;
1070+
1071+ p_handler -> function = t_pointer;
10381072 }
10391073 else if (MCStringIsEqualToCString (*t_language, " cpp" , kMCStringOptionCompareExact ))
10401074 {
@@ -1083,7 +1117,7 @@ static bool MCScriptResolveForeignFunctionBinding(MCScriptForeignHandlerDefiniti
10831117static bool MCScriptPrepareForeignFunction (MCScriptFrame *p_frame, MCScriptInstanceRef p_instance, MCScriptForeignHandlerDefinition *p_handler, bool p_throw, bool & r_bound)
10841118{
10851119 ffi_abi t_abi;
1086- if (!MCScriptResolveForeignFunctionBinding (p_handler, t_abi, p_throw, r_bound))
1120+ if (!MCScriptResolveForeignFunctionBinding (p_instance, p_handler, t_abi, p_throw, r_bound))
10871121 return false ;
10881122
10891123 if (!p_throw && !r_bound)
0 commit comments