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];
}
|