void scfFactory::IncRef () { csRefTrackerAccess::TrackIncRef (this, scfRefCount); if (!Library && (LibraryName != csInvalidStringID)) { size_t libidx = LibraryRegistry->FindLibrary(LibraryName); if (libidx != (size_t)-1) Library = (scfSharedLibrary *)LibraryRegistry->Get (libidx); else Library = new scfSharedLibrary (LibraryName, FactoryClass); if (Library->ok ()) { csString sym; sym << FactoryClass << "_Create"; CreateFunc = (scfFactoryFunc)csGetLibrarySymbol(Library->LibraryHandle, sym); if (CreateFunc == 0) csPrintLibraryError(sym); } if (!Library->ok () || CreateFunc == 0) { Library = 0; return; // Signify that IncRef() failed by _not_ incrementing count. } Library->IncRef (); } scfRefCount++; }
scfSharedLibrary::scfSharedLibrary (csStringID libraryName, const char *core) { LibraryRegistry->Push (this); RefCount = 0; LibraryName = libraryName; const char* lib = get_library_name(LibraryName); if (PrivateSCF->IsVerbose(SCF_VERBOSE_PLUGIN_LOAD)) csPrintfErr("SCF_NOTIFY: loading plugin %s to satisfy request for %s\n", lib, core); LibraryHandle = csLoadLibrary (lib); if (LibraryHandle != 0) { csString sym; sym << core << "_scfInitialize"; initFunc = (scfInitFunc)csGetLibrarySymbol(LibraryHandle, sym); if (!initFunc) { csPrintfErr("SCF_ERROR: %s doesn't export %s\n", CS::Quote::Single (lib), CS::Quote::Single (sym.GetData())); csPrintLibraryError (sym); } sym.Clear (); sym << core << "_scfFinalize"; finisFunc = (scfFinisFunc)csGetLibrarySymbol(LibraryHandle, sym); if (!finisFunc) { csPrintfErr("SCF_ERROR: %s doesn't export %s\n", CS::Quote::Single (lib), CS::Quote::Single (sym.GetData())); csPrintLibraryError (sym); } if (initFunc && finisFunc) initFunc (PrivateSCF); } else csPrintLibraryError (lib); }
csLibraryHandle csLoadLibrary (const char* iName) { csLibraryHandle handle; DWORD errorCode; CS_ALLOC_STACK_ARRAY (char, dllPath, strlen (iName) + 5); strcpy (dllPath, iName); char* dot = strrchr (dllPath, '.'); if ((!dot) || (strcasecmp (dot, ".dll") != 0)) { if (dot && (strcasecmp (dot, ".csplugin") == 0)) { strcpy (dot, ".dll"); } else { strcat (dllPath, ".dll"); } } handle = LoadLibraryEx (dllPath, 0, LOADLIBEX_FLAGS); errorCode = GetLastError(); #ifdef __CYGWIN__ // A load attempt might fail if the DLL depends implicitly upon some other // DLLs which reside in the Cygwin /bin directory. To deal with this case, we // add the Cygwin /bin directory to the PATH environment variable and retry. if (handle == 0) { char *OLD_PATH = new char[4096]; char *DLLDIR = new char[1024]; GetEnvironmentVariable("PATH", OLD_PATH, 4096); if (cygwin_conv_to_win32_path ("/bin/",DLLDIR)) { ErrorMessages.Push( "LoadLibraryEx() '/bin/' Cygwin/Win32 path conversion failed."); delete[] DLLDIR; delete[] OLD_PATH; return 0; } SetEnvironmentVariable("PATH", DLLDIR); handle = LoadLibraryEx (dllPath, 0, LOADLIBEX_FLAGS); errorCode = GetLastError(); SetEnvironmentVariable("PATH", OLD_PATH); delete[] DLLDIR; delete[] OLD_PATH; } #endif if (handle == 0) { char *buf = cswinGetErrorMessage (errorCode); csString s; s << "LoadLibraryEx(" << dllPath << ") error " << (int)errorCode << ": " << buf; ErrorMessages.Push (s); delete[] buf; return 0; } typedef const char* (*pfnGetPluginCompiler)(); pfnGetPluginCompiler get_plugin_compiler = (pfnGetPluginCompiler) csGetLibrarySymbol (handle, "plugin_compiler"); if (!get_plugin_compiler) { csString s; s << dllPath << ": DLL does not export \"plugin_compiler\"."; ErrorMessages.Push (s); FreeLibrary ((HMODULE)handle); return 0; } const char* plugin_compiler = get_plugin_compiler(); if (strcmp(plugin_compiler, CS_COMPILER_NAME) != 0) { csString s; s << dllPath << ": plugin compiler does not match application compiler: " << plugin_compiler << " != " CS_COMPILER_NAME; ErrorMessages.Push (s); FreeLibrary ((HMODULE)handle); return 0; } return handle; }