Overview
Comment: | OFPlugin: Completely redesign API |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA3-256: |
a74bff96c4dae6909ee0760190bde62a |
User & Date: | js on 2022-06-17 17:12:52 |
Other Links: | manifest | tags |
Context
2022-06-17
| ||
20:04 | Make GCC happy again check-in: b29bfe6485 user: js tags: trunk | |
17:12 | OFPlugin: Completely redesign API check-in: a74bff96c4 user: js tags: trunk | |
14:36 | Better workaround for Clang bug on Windows check-in: 658caa441b user: js tags: trunk | |
Changes
Modified src/OFPlugin.h from [9b033eeb96] to [4badab4fb7].
︙ | ︙ | |||
16 17 18 19 20 21 22 | #import "OFObject.h" @class OFString; #ifndef OF_WINDOWS # include <dlfcn.h> typedef void *OFPluginHandle; | < < < < < < < < < < | < < < > | < | > > > | | | | > > | < > > | > > | > | > > > > | > | < < | > > > > > > > | | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | #import "OFObject.h" @class OFString; #ifndef OF_WINDOWS # include <dlfcn.h> typedef void *OFPluginHandle; #else # include <windows.h> typedef HMODULE OFPluginHandle; #endif OF_ASSUME_NONNULL_BEGIN /** * @class OFPlugin OFPlugin.h ObjFW/OFPlugin.h * * @brief A class representing a loaded plugin (shared library). * */ OF_SUBCLASSING_RESTRICTED @interface OFPlugin: OFObject { OFPluginHandle _handle; } /** * @brief Returns the plugin path for a plugin with the specified name. * * E.g. on ELF systems, it appends .so, while on macOS and iOS, it creates the * appropriate plugin path. This can also be prefixed by a directory. * * @param name The name to return the plugin path for * @return The plugin path */ + (OFString *)pathForName: (OFString *)name; /** * @brief Creates a new OFPlugin by loading the plugin with the specified path. * * @param path The path to the plugin file. The suffix is appended * automatically. * @return An new, autoreleased OFPlugin */ + (instancetype)pluginWithPath: (OFString *)path; /** * @brief Initializes an already allocated OFPlugin by loading the plugin with * the specified path. * * @param path The path to the plugin file. The suffix is appended * automatically. * @return An initialized OFPlugin */ - (instancetype)initWithPath: (OFString *)path; /** * @brief Returns the address for the specified symbol, or `nil` if not found. * * @param symbol The symbol to return the address for * @return The address for the speccified symbol, or `nil` if not found */ - (nullable void *)addressForSymbol: (OFString *)symbol; @end OF_ASSUME_NONNULL_END |
Modified src/OFPlugin.m from [e14701ced1] to [8ad69b7ef8].
︙ | ︙ | |||
26 27 28 29 30 31 32 | #import "OFLocale.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFInitializationFailedException.h" #import "OFLoadPluginFailedException.h" | | > > | | < | > | | < | | > > > | > | | < > > > > > | < | < < < < < < < < < < | < < < < < < < < < < | > > | > > | | | | < < | < < | < < < < < < | < < | | | | < < < < < < < | < < < < < < < < < | | | | | | > > > | > > > > > > | > > > < < | 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | #import "OFLocale.h" #import "OFString.h" #import "OFSystemInfo.h" #import "OFInitializationFailedException.h" #import "OFLoadPluginFailedException.h" #ifndef RTLD_LAZY # define RTLD_LAZY 0 #endif @implementation OFPlugin + (instancetype)pluginWithPath: (OFString *)path { return [[[self alloc] initWithPath: path] autorelease]; } + (OFString *)pathForName: (OFString *)name { #if defined(OF_MACOS) return [name stringByAppendingFormat: @".bundle/Contents/MacOS/%@", name.lastPathComponent]; #elif defined(OF_IOS) return [name stringByAppendingFormat: @".bundle/%@", name.lastPathComponent]; #else return [name stringByAppendingString: @PLUGIN_SUFFIX]; #endif } - (instancetype)initWithPath: (OFString *)path { self = [super init]; @try { void *pool = objc_autoreleasePoolPush(); #ifndef OF_WINDOWS _handle = dlopen( [path cStringWithEncoding: [OFLocale encoding]], RTLD_LAZY); #else if ([OFSystemInfo isWindowsNT]) _handle = LoadLibraryW(path.UTF16String); else _handle LoadLibraryA( [path cStringWithEncoding: [OFLocale encoding]]); #endif if (_handle == NULL) { #ifndef OF_WINDOWS OFString *error = [OFString stringWithCString: dlerror() encoding: [OFLocale encoding]]; #else OFString *error = nil; #endif @throw [OFLoadPluginFailedException exceptionWithPath: path error: error]; } objc_autoreleasePoolPop(pool); } @catch (id e) { [self release]; @throw e; } return self; } - (void *)addressForSymbol: (OFString *)symbol { #ifndef OF_WINDOWS return dlsym(_handle, [symbol cStringWithEncoding: [OFLocale encoding]]); #else return (void *)(uintptr_t)GetProcAddress(_handle, [symbol cStringWithEncoding: [OFLocale encoding]]); #endif } - (void)dealloc { #ifndef OF_WINDOWS dlclose(_handle); #else FreeLibrary(_handle); #endif [super dealloc]; } @end |
Modified tests/OFPluginTests.m from [cebf7a6561] to [d69a23db27].
︙ | ︙ | |||
16 17 18 19 20 21 22 | #include "config.h" #import "TestsAppDelegate.h" #import "plugin/TestPlugin.h" #ifndef OF_IOS | | | > > > | > > | | > > > > | > > > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #include "config.h" #import "TestsAppDelegate.h" #import "plugin/TestPlugin.h" #ifndef OF_IOS static OFString *const pluginName = @"plugin/TestPlugin"; #else static OFString *const pluginName = @"PlugIns/TestPlugin"; #endif static OFString *const module = @"OFPlugin"; @implementation TestsAppDelegate (OFPluginTests) - (void)pluginTests { void *pool = objc_autoreleasePoolPush(); OFString *path; OFPlugin *plugin; Class (*class)(void); TestPlugin *test; TEST(@"+[pathForName:]", (path = [OFPlugin pathForName: pluginName])) TEST(@"+[pluginWithPath:]", (plugin = [OFPlugin pluginWithPath: path])) TEST(@"-[addressForSymbol:]", (class = (Class (*)(void))[plugin addressForSymbol: @"class"])) test = [[class() alloc] init]; @try { TEST(@"TestPlugin's -[test:]", [test test: 1234] == 2468) } @finally { [test release]; } objc_autoreleasePoolPop(pool); } @end |
Modified tests/plugin/TestPlugin.h from [52670dca56] to [2f9aa9b796].
︙ | ︙ | |||
9 10 11 12 13 14 15 | * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ | | | | 9 10 11 12 13 14 15 16 17 18 19 20 | * * Alternatively, it may be distributed under the terms of the GNU General * Public License, either version 2 or 3, which can be found in the file * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" @interface TestPlugin: OFObject - (int)test: (int)num; @end |
Modified tests/plugin/TestPlugin.m from [b5310ee637] to [5616dbe160].
︙ | ︙ | |||
40 41 42 43 44 45 46 | @implementation TestPlugin - (int)test: (int)num { return num * 2; } @end | < > | | | 40 41 42 43 44 45 46 47 48 49 50 51 | @implementation TestPlugin - (int)test: (int)num { return num * 2; } @end Class class(void) { return [TestPlugin class]; } |