├── .gitignore ├── LICENSE ├── README.md ├── common ├── Injector │ └── goatnative │ │ └── Injector.h └── main.cpp ├── osx └── Injector.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ └── xcshareddata │ │ └── Injector.xccheckout │ └── xcuserdata │ └── max.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── Injector.xcscheme │ └── xcschememanagement.plist └── win └── inject ├── inject.sln └── inject.vcxproj /.gitignore: -------------------------------------------------------------------------------- 1 | win/inject/inject.opensdf 2 | win/inject/inject.sdf 3 | win/inject/Debug 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 GoatHunter 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # goatnative-inject 2 | C++11 Dependency Injection (IoC - inversion of control) class using variadic templates and shared pointers. 3 | This ought to give a good example of variadic templates usage and other C++11 features such as auto and shared_ptr. 4 | 5 | The implementation behind the goatnative::Inject is taken from www.codeproject.com/Articles/567981/AnplusIOCplusContainerplususingplusVariadicplusTem 6 | I've extended that implementation by: 7 | 8 | * Adding a registerInterface method that lets you map interfaces to previously registered instance classes. 9 | 10 | ## Features 11 | * Register types to their dependencies. 12 | * Register as singleton. 13 | * Register interfaces to to concrete types. 14 | * Thread safe. 15 | 16 | ## Limits 17 | * Currently injection is done only via constructor. 18 | * Injectee constructors are expected to have shared_ptr to each injected types 19 | 20 | ## Examples 21 | 22 | ### Example - Hello world 23 | 24 | ```cpp 25 | #include "Injector/goatnative/Injector.h" 26 | #include 27 | 28 | using goatnative::Injector; 29 | 30 | class IHello 31 | { 32 | public: 33 | virtual void hello() const = 0; 34 | virtual ~IHello() = default; 35 | }; 36 | 37 | 38 | class Hello : public IHello 39 | { 40 | public: 41 | virtual void hello() const 42 | { 43 | std::cout << "hello world!" << std::endl; 44 | } 45 | }; 46 | 47 | 48 | int main(int argc, const char** argv) 49 | { 50 | Injector injector; 51 | 52 | // Let's register the concrete class 53 | injector.registerClass(); 54 | 55 | // Now register IHello with Hello so that each time we ask for IHello 56 | // We get Hello - 57 | injector.registerInterface(); 58 | 59 | auto helloInstance = injector.getInstance(); 60 | 61 | helloInstance->hello(); 62 | } 63 | ``` 64 | 65 | ### Example - Singleton Class 66 | ```cpp 67 | #include 68 | #include 69 | 70 | #include "Injector/goatnative/Injector.h" 71 | 72 | using goatnative::Injector; 73 | 74 | class IExecutor 75 | { 76 | public: 77 | virtual void execute(std::function func) = 0; 78 | virtual ~IExecutor() = default; 79 | }; 80 | 81 | class SyncExecutor : public IExecutor 82 | { 83 | public: 84 | void execute(std::function func) override 85 | { 86 | func(); 87 | } 88 | }; 89 | 90 | int main(int argc, const char * argv[]) { 91 | Injector injector; 92 | 93 | // Here we're registering IExecutor with SyncExecutor as singleton 94 | injector.registerSingleton(); 95 | injector.registerInterface(); 96 | 97 | // Whenever we'll ask for IExecutor we'll get the same instance of SyncExecutor 98 | auto executor1 = injector.getInstance(); 99 | auto executor2 = injector.getInstance(); 100 | 101 | // Compare returned pointer which are expected to be the same 102 | assert(executor1.get() == executor2.get()); 103 | return 0; 104 | } 105 | ``` 106 | ### Example - map to an existing instance 107 | ```cpp 108 | #include 109 | #include 110 | 111 | #include "Injector/goatnative/Injector.h" 112 | 113 | using goatnative::Injector; 114 | 115 | class NullObject 116 | { 117 | }; 118 | 119 | int main(int argc, const char * argv[]) { 120 | Injector injector; 121 | 122 | // Here's an example of how to register a manually created instance of an object 123 | auto nullInstance = std::make_shared(); 124 | 125 | injector.registerInstance(nullInstance); 126 | 127 | auto null1 = injector.getInstance(); 128 | auto null2 = injector.getInstance(); 129 | 130 | assert(null1.get() == null2.get()); 131 | assert(null1.get() == nullInstance.get()); 132 | return 0; 133 | } 134 | ``` 135 | 136 | ### Example - class with dependencies 137 | ```cpp 138 | #include 139 | #include 140 | #include 141 | 142 | #include "Injector/goatnative/Injector.h" 143 | 144 | using std::cout; 145 | using std::endl; 146 | using std::shared_ptr; 147 | using std::string; 148 | 149 | using goatnative::Injector; 150 | 151 | class ICar 152 | { 153 | public: 154 | virtual void startIgnition() = 0; 155 | virtual ~ICar() = default; 156 | }; 157 | 158 | class IEngine 159 | { 160 | public: 161 | virtual double getVolume() const = 0; 162 | virtual ~IEngine() = default; 163 | }; 164 | 165 | class IWheels 166 | { 167 | public: 168 | virtual bool inflated() const = 0; 169 | virtual ~IWheels() = default; 170 | }; 171 | 172 | class Engine : public IEngine 173 | { 174 | public: 175 | virtual double getVolume() const override 176 | { 177 | return 10.5; 178 | } 179 | }; 180 | 181 | class Wheels : public IWheels 182 | { 183 | public: 184 | virtual bool inflated() const override 185 | { 186 | return false; 187 | } 188 | }; 189 | 190 | class Car : public ICar 191 | { 192 | public: 193 | Car(shared_ptr engine, shared_ptr wheels) : _engine(engine), _wheels(wheels) 194 | { 195 | 196 | } 197 | 198 | virtual void startIgnition() 199 | { 200 | std::cout << "starting ignition, engine volume: " << _engine->getVolume() 201 | << ", wheels inflated? " << _wheels->inflated() << std::endl; 202 | } 203 | 204 | private: 205 | shared_ptr _engine; 206 | shared_ptr _wheels; 207 | }; 208 | 209 | 210 | int main(int argc, const char * argv[]) { 211 | Injector injector; 212 | 213 | // Here's an example of a more complex graph of objects tied together 214 | // using Injector - 215 | 216 | // Engine 217 | injector.registerClass(); 218 | injector.registerInterface(); 219 | 220 | // Wheels 221 | injector.registerClass(); 222 | injector.registerInterface(); 223 | 224 | // Register car with its dependencies - IEngine and IWheels (required by its ctor) 225 | injector.registerClass(); 226 | injector.registerInterface(); 227 | 228 | // Car is instansiated with instances of Engine, Wheels and Car automatically! 229 | auto car = injector.getInstance(); 230 | car->startIgnition(); 231 | 232 | return 0; 233 | } 234 | ``` 235 | 236 | * See more examples in main.cpp 237 | 238 | ## TODO 239 | * Move tests from main.cpp to Google Test. 240 | -------------------------------------------------------------------------------- /common/Injector/goatnative/Injector.h: -------------------------------------------------------------------------------- 1 | // 2 | // Injector.h 3 | // Injector 4 | // 5 | // Created by Max Raskin on 1/17/15. 6 | // Copyright (c) 2015 Max Raskin. All rights reserved. 7 | // 8 | 9 | #ifndef Injector_Injector_h 10 | #define Injector_Injector_h 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace goatnative 20 | { 21 | using std::shared_ptr; 22 | using std::make_shared; 23 | using std::function; 24 | using std::pair; 25 | using std::unordered_map; 26 | using std::size_t; 27 | using std::recursive_mutex; 28 | using std::lock_guard; 29 | 30 | // 31 | // Injector 32 | // Inversion of Control (IoC) container. 33 | // Let's you create a type-safe mapping of class hierarchies by injecting constructor arguments. 34 | // 35 | // Idea and code based upon: 36 | // http://www.codeproject.com/Articles/567981/AnplusIOCplusContainerplususingplusVariadicplusTem 37 | // 38 | // 39 | // See usage examples @ https://github.com/GoatHunter/goatnative-inject 40 | class Injector 41 | { 42 | public: 43 | template 44 | Injector& registerClass() 45 | { 46 | lock_guard lockGuard{ _mutex }; 47 | 48 | auto creator = [this]() -> T* 49 | { 50 | return new T(getInstance()...); 51 | }; 52 | 53 | _typesToCreators.insert(pair>{typeid(T).hash_code(), creator} ); 54 | 55 | return *this; 56 | } 57 | 58 | template 59 | Injector& registerInstance(shared_ptr instance) 60 | { 61 | lock_guard lockGuard{ _mutex }; 62 | 63 | shared_ptr holder = shared_ptr>{new Holder{instance}}; 64 | 65 | _typesToInstances.insert(pair>{typeid(T).hash_code(), holder}); 66 | 67 | return *this; 68 | } 69 | 70 | template 71 | Injector& registerSingleton() 72 | { 73 | lock_guard lockGuard{ _mutex }; 74 | 75 | auto instance = make_shared(getInstance()...); 76 | 77 | return registerInstance(instance); 78 | } 79 | 80 | template 81 | Injector& registerInterface() 82 | { 83 | lock_guard lockGuard{ _mutex }; 84 | 85 | auto instanceGetter = [this]() -> shared_ptr 86 | { 87 | auto instance = getInstance(); 88 | shared_ptr holder = shared_ptr>{new Holder{ instance }}; 89 | 90 | return holder; 91 | }; 92 | 93 | _interfacesToInstanceGetters.insert(pair()>>{typeid(Interface).hash_code(), instanceGetter}); 94 | 95 | return *this; 96 | } 97 | 98 | 99 | template 100 | shared_ptr getInstance() 101 | { 102 | lock_guard lockGuard{ _mutex }; 103 | 104 | // Try getting registered singleton or instance. 105 | if (_typesToInstances.find(typeid(T).hash_code()) != _typesToInstances.end()) 106 | { 107 | // get as reference to avoid refcount increment 108 | auto& iholder = _typesToInstances[typeid(T).hash_code()]; 109 | 110 | auto holder = dynamic_cast*>(iholder.get()); 111 | return holder->_instance; 112 | } // Otherwise attempt getting the creator and act as factory. 113 | else if (_typesToCreators.find(typeid(T).hash_code()) != _typesToCreators.end()) 114 | { 115 | auto& creator = _typesToCreators[typeid(T).hash_code()]; 116 | 117 | return shared_ptr{(T*)creator()}; 118 | } 119 | else if (_interfacesToInstanceGetters.find(typeid(T).hash_code()) != _interfacesToInstanceGetters.end()) 120 | { 121 | auto& instanceGetter = _interfacesToInstanceGetters[typeid(T).hash_code()]; 122 | 123 | auto iholder = instanceGetter(); 124 | 125 | auto holder = dynamic_cast*>(iholder.get()); 126 | return holder->_instance; 127 | } 128 | 129 | // If you debug, in some debuggers (e.g Apple's lldb in Xcode) it will breakpoint in this assert 130 | // and by looking in the stack trace you'll be able to see which class you forgot to map. 131 | assert(false && "One of your injected dependencies isn't mapped, please check your mappings."); 132 | 133 | return nullptr; 134 | } 135 | 136 | private: 137 | 138 | struct IHolder 139 | { 140 | virtual ~IHolder() = default; 141 | }; 142 | 143 | template 144 | struct Holder : public IHolder 145 | { 146 | Holder(shared_ptr instance) : _instance(instance) 147 | {} 148 | 149 | shared_ptr _instance; 150 | }; 151 | 152 | // Holds instances - keeps singletons and custom registered instances 153 | unordered_map> _typesToInstances; 154 | // Holds creators used to instansiate a type 155 | unordered_map> _typesToCreators; 156 | 157 | unordered_map()>> _interfacesToInstanceGetters; 158 | 159 | recursive_mutex _mutex; 160 | 161 | }; 162 | } // namespace goatnative 163 | 164 | #endif 165 | -------------------------------------------------------------------------------- /common/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // Injector 4 | // 5 | // Created by Max Raskin on 1/17/15. 6 | // Copyright (c) 2015 Max Raskin. All rights reserved. 7 | // 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include "Injector/goatnative/Injector.h" 14 | 15 | using std::cout; 16 | using std::endl; 17 | using std::shared_ptr; 18 | using std::string; 19 | 20 | using goatnative::Injector; 21 | 22 | class IFile 23 | { 24 | virtual void open() = 0; 25 | }; 26 | 27 | class Win32File : public IFile 28 | { 29 | void open() override 30 | { 31 | cout << "opening!!!" << endl; 32 | } 33 | }; 34 | 35 | class IConcurrency 36 | { 37 | public: 38 | virtual void createMutex() = 0; 39 | virtual ~IConcurrency() = default; 40 | }; 41 | 42 | class IFileSystem 43 | { 44 | public: 45 | virtual void writeFile(const string& fileName) = 0; 46 | virtual ~IFileSystem() = default; 47 | }; 48 | 49 | class INotifier 50 | { 51 | public: 52 | virtual void notify(const string& message, const string& target) = 0; 53 | virtual ~INotifier() = default; 54 | }; 55 | 56 | class Concurrency : public IConcurrency 57 | { 58 | public: 59 | void createMutex() override 60 | { 61 | cout << "Creating mutex" << endl; 62 | } 63 | }; 64 | 65 | class FileSystem : public IFileSystem 66 | { 67 | public: 68 | void writeFile(const string& fileName) override 69 | { 70 | cout << "Writing" << fileName << endl; 71 | } 72 | }; 73 | 74 | class Notifier : public INotifier 75 | { 76 | public: 77 | void notify(const string& message, const string& target) override 78 | { 79 | cout << "Notifying " << target << " with message: " << message << endl; 80 | } 81 | 82 | }; 83 | 84 | class ServicesProvider 85 | { 86 | public: 87 | ServicesProvider(shared_ptr concurency, 88 | shared_ptr fileSystem, 89 | shared_ptr notifier) 90 | : _concurency(concurency), _fileSystem(fileSystem), _notifier(notifier) 91 | { 92 | 93 | } 94 | 95 | shared_ptr concurrency() 96 | { 97 | return _concurency; 98 | } 99 | 100 | shared_ptr filesystem() 101 | { 102 | return _fileSystem; 103 | } 104 | 105 | shared_ptr notifier() 106 | { 107 | return _notifier; 108 | } 109 | 110 | private: 111 | shared_ptr _concurency; 112 | shared_ptr _fileSystem; 113 | shared_ptr _notifier; 114 | }; 115 | 116 | //////////////////////////////////////////// 117 | 118 | void testSingleton() 119 | { 120 | Injector injector; 121 | 122 | injector.registerSingleton(); 123 | injector.registerInterface(); 124 | auto notifier = injector.getInstance(); 125 | auto notifier2 = injector.getInstance(); 126 | 127 | assert(notifier == notifier2); 128 | 129 | } 130 | 131 | void testBuildWholeGraph() 132 | { 133 | 134 | Injector injector; 135 | 136 | injector.registerSingleton(); 137 | injector.registerInterface(); 138 | 139 | injector.registerSingleton(); 140 | injector.registerInterface(); 141 | 142 | injector.registerSingleton(); 143 | injector.registerInterface(); 144 | 145 | injector.registerSingleton(); 146 | 147 | auto services = injector.getInstance(); 148 | 149 | assert(services->notifier()); 150 | assert(services->filesystem()); 151 | assert(services->concurrency()); 152 | 153 | assert(services->notifier().get() == injector.getInstance().get()); 154 | assert(services->concurrency().get() == injector.getInstance().get()); 155 | assert(services->filesystem().get() == injector.getInstance().get()); 156 | } 157 | 158 | 159 | void testInterfaceBasedFactory() 160 | { 161 | 162 | Injector injector; 163 | 164 | injector.registerClass(); 165 | injector.registerInterface(); 166 | 167 | auto notifier1 = injector.getInstance(); 168 | auto notifier2 = injector.getInstance(); 169 | 170 | assert(notifier1.get() != notifier2.get()); 171 | } 172 | 173 | 174 | void testFactory() 175 | { 176 | Injector injector; 177 | 178 | injector.registerClass(); 179 | assert(injector.getInstance().get() != injector.getInstance().get()); 180 | } 181 | 182 | int main(int argc, const char * argv[]) { 183 | // TODO - move tests to Google Test 184 | testSingleton(); 185 | testBuildWholeGraph(); 186 | testFactory(); 187 | testInterfaceBasedFactory(); 188 | 189 | return 0; 190 | } 191 | 192 | 193 | -------------------------------------------------------------------------------- /osx/Injector.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 501A8FEF1A6AF3B400E9F2CA /* main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 501A8FEE1A6AF3B400E9F2CA /* main.cpp */; }; 11 | /* End PBXBuildFile section */ 12 | 13 | /* Begin PBXCopyFilesBuildPhase section */ 14 | 5010FA8D1A6AA91F00CC6F1E /* CopyFiles */ = { 15 | isa = PBXCopyFilesBuildPhase; 16 | buildActionMask = 2147483647; 17 | dstPath = /usr/share/man/man1/; 18 | dstSubfolderSpec = 0; 19 | files = ( 20 | ); 21 | runOnlyForDeploymentPostprocessing = 1; 22 | }; 23 | /* End PBXCopyFilesBuildPhase section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | 5010FA8F1A6AA91F00CC6F1E /* Injector */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Injector; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | 501A8FED1A6AF3B400E9F2CA /* Injector.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Injector.h; sourceTree = ""; }; 28 | 501A8FEE1A6AF3B400E9F2CA /* main.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = main.cpp; path = ../common/main.cpp; sourceTree = ""; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | 5010FA8C1A6AA91F00CC6F1E /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | ); 37 | runOnlyForDeploymentPostprocessing = 0; 38 | }; 39 | /* End PBXFrameworksBuildPhase section */ 40 | 41 | /* Begin PBXGroup section */ 42 | 5010FA861A6AA91F00CC6F1E = { 43 | isa = PBXGroup; 44 | children = ( 45 | 501A8FEB1A6AF3B400E9F2CA /* Injector */, 46 | 501A8FEE1A6AF3B400E9F2CA /* main.cpp */, 47 | 5010FA901A6AA91F00CC6F1E /* Products */, 48 | ); 49 | sourceTree = ""; 50 | }; 51 | 5010FA901A6AA91F00CC6F1E /* Products */ = { 52 | isa = PBXGroup; 53 | children = ( 54 | 5010FA8F1A6AA91F00CC6F1E /* Injector */, 55 | ); 56 | name = Products; 57 | sourceTree = ""; 58 | }; 59 | 501A8FEB1A6AF3B400E9F2CA /* Injector */ = { 60 | isa = PBXGroup; 61 | children = ( 62 | 501A8FEC1A6AF3B400E9F2CA /* goatnative */, 63 | ); 64 | name = Injector; 65 | path = ../common/Injector; 66 | sourceTree = ""; 67 | }; 68 | 501A8FEC1A6AF3B400E9F2CA /* goatnative */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | 501A8FED1A6AF3B400E9F2CA /* Injector.h */, 72 | ); 73 | path = goatnative; 74 | sourceTree = ""; 75 | }; 76 | /* End PBXGroup section */ 77 | 78 | /* Begin PBXNativeTarget section */ 79 | 5010FA8E1A6AA91F00CC6F1E /* Injector */ = { 80 | isa = PBXNativeTarget; 81 | buildConfigurationList = 5010FA961A6AA92000CC6F1E /* Build configuration list for PBXNativeTarget "Injector" */; 82 | buildPhases = ( 83 | 5010FA8B1A6AA91F00CC6F1E /* Sources */, 84 | 5010FA8C1A6AA91F00CC6F1E /* Frameworks */, 85 | 5010FA8D1A6AA91F00CC6F1E /* CopyFiles */, 86 | ); 87 | buildRules = ( 88 | ); 89 | dependencies = ( 90 | ); 91 | name = Injector; 92 | productName = Injector; 93 | productReference = 5010FA8F1A6AA91F00CC6F1E /* Injector */; 94 | productType = "com.apple.product-type.tool"; 95 | }; 96 | /* End PBXNativeTarget section */ 97 | 98 | /* Begin PBXProject section */ 99 | 5010FA871A6AA91F00CC6F1E /* Project object */ = { 100 | isa = PBXProject; 101 | attributes = { 102 | LastUpgradeCheck = 0610; 103 | ORGANIZATIONNAME = "Max Raskin"; 104 | TargetAttributes = { 105 | 5010FA8E1A6AA91F00CC6F1E = { 106 | CreatedOnToolsVersion = 6.1; 107 | }; 108 | }; 109 | }; 110 | buildConfigurationList = 5010FA8A1A6AA91F00CC6F1E /* Build configuration list for PBXProject "Injector" */; 111 | compatibilityVersion = "Xcode 3.2"; 112 | developmentRegion = English; 113 | hasScannedForEncodings = 0; 114 | knownRegions = ( 115 | en, 116 | ); 117 | mainGroup = 5010FA861A6AA91F00CC6F1E; 118 | productRefGroup = 5010FA901A6AA91F00CC6F1E /* Products */; 119 | projectDirPath = ""; 120 | projectRoot = ""; 121 | targets = ( 122 | 5010FA8E1A6AA91F00CC6F1E /* Injector */, 123 | ); 124 | }; 125 | /* End PBXProject section */ 126 | 127 | /* Begin PBXSourcesBuildPhase section */ 128 | 5010FA8B1A6AA91F00CC6F1E /* Sources */ = { 129 | isa = PBXSourcesBuildPhase; 130 | buildActionMask = 2147483647; 131 | files = ( 132 | 501A8FEF1A6AF3B400E9F2CA /* main.cpp in Sources */, 133 | ); 134 | runOnlyForDeploymentPostprocessing = 0; 135 | }; 136 | /* End PBXSourcesBuildPhase section */ 137 | 138 | /* Begin XCBuildConfiguration section */ 139 | 5010FA941A6AA92000CC6F1E /* Debug */ = { 140 | isa = XCBuildConfiguration; 141 | buildSettings = { 142 | ALWAYS_SEARCH_USER_PATHS = NO; 143 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 144 | CLANG_CXX_LIBRARY = "libc++"; 145 | CLANG_ENABLE_MODULES = YES; 146 | CLANG_ENABLE_OBJC_ARC = YES; 147 | CLANG_WARN_BOOL_CONVERSION = YES; 148 | CLANG_WARN_CONSTANT_CONVERSION = YES; 149 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 150 | CLANG_WARN_EMPTY_BODY = YES; 151 | CLANG_WARN_ENUM_CONVERSION = YES; 152 | CLANG_WARN_INT_CONVERSION = YES; 153 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 154 | CLANG_WARN_UNREACHABLE_CODE = YES; 155 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 156 | COPY_PHASE_STRIP = NO; 157 | ENABLE_STRICT_OBJC_MSGSEND = YES; 158 | GCC_C_LANGUAGE_STANDARD = gnu99; 159 | GCC_DYNAMIC_NO_PIC = NO; 160 | GCC_OPTIMIZATION_LEVEL = 0; 161 | GCC_PREPROCESSOR_DEFINITIONS = ( 162 | "DEBUG=1", 163 | "$(inherited)", 164 | ); 165 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 166 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 167 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 168 | GCC_WARN_UNDECLARED_SELECTOR = YES; 169 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 170 | GCC_WARN_UNUSED_FUNCTION = YES; 171 | GCC_WARN_UNUSED_VARIABLE = YES; 172 | MACOSX_DEPLOYMENT_TARGET = 10.10; 173 | MTL_ENABLE_DEBUG_INFO = YES; 174 | ONLY_ACTIVE_ARCH = YES; 175 | SDKROOT = macosx; 176 | }; 177 | name = Debug; 178 | }; 179 | 5010FA951A6AA92000CC6F1E /* Release */ = { 180 | isa = XCBuildConfiguration; 181 | buildSettings = { 182 | ALWAYS_SEARCH_USER_PATHS = NO; 183 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 184 | CLANG_CXX_LIBRARY = "libc++"; 185 | CLANG_ENABLE_MODULES = YES; 186 | CLANG_ENABLE_OBJC_ARC = YES; 187 | CLANG_WARN_BOOL_CONVERSION = YES; 188 | CLANG_WARN_CONSTANT_CONVERSION = YES; 189 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 190 | CLANG_WARN_EMPTY_BODY = YES; 191 | CLANG_WARN_ENUM_CONVERSION = YES; 192 | CLANG_WARN_INT_CONVERSION = YES; 193 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 194 | CLANG_WARN_UNREACHABLE_CODE = YES; 195 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 196 | COPY_PHASE_STRIP = YES; 197 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 198 | ENABLE_NS_ASSERTIONS = NO; 199 | ENABLE_STRICT_OBJC_MSGSEND = YES; 200 | GCC_C_LANGUAGE_STANDARD = gnu99; 201 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 202 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 203 | GCC_WARN_UNDECLARED_SELECTOR = YES; 204 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 205 | GCC_WARN_UNUSED_FUNCTION = YES; 206 | GCC_WARN_UNUSED_VARIABLE = YES; 207 | MACOSX_DEPLOYMENT_TARGET = 10.10; 208 | MTL_ENABLE_DEBUG_INFO = NO; 209 | SDKROOT = macosx; 210 | }; 211 | name = Release; 212 | }; 213 | 5010FA971A6AA92000CC6F1E /* Debug */ = { 214 | isa = XCBuildConfiguration; 215 | buildSettings = { 216 | PRODUCT_NAME = "$(TARGET_NAME)"; 217 | }; 218 | name = Debug; 219 | }; 220 | 5010FA981A6AA92000CC6F1E /* Release */ = { 221 | isa = XCBuildConfiguration; 222 | buildSettings = { 223 | PRODUCT_NAME = "$(TARGET_NAME)"; 224 | }; 225 | name = Release; 226 | }; 227 | /* End XCBuildConfiguration section */ 228 | 229 | /* Begin XCConfigurationList section */ 230 | 5010FA8A1A6AA91F00CC6F1E /* Build configuration list for PBXProject "Injector" */ = { 231 | isa = XCConfigurationList; 232 | buildConfigurations = ( 233 | 5010FA941A6AA92000CC6F1E /* Debug */, 234 | 5010FA951A6AA92000CC6F1E /* Release */, 235 | ); 236 | defaultConfigurationIsVisible = 0; 237 | defaultConfigurationName = Release; 238 | }; 239 | 5010FA961A6AA92000CC6F1E /* Build configuration list for PBXNativeTarget "Injector" */ = { 240 | isa = XCConfigurationList; 241 | buildConfigurations = ( 242 | 5010FA971A6AA92000CC6F1E /* Debug */, 243 | 5010FA981A6AA92000CC6F1E /* Release */, 244 | ); 245 | defaultConfigurationIsVisible = 0; 246 | defaultConfigurationName = Release; 247 | }; 248 | /* End XCConfigurationList section */ 249 | }; 250 | rootObject = 5010FA871A6AA91F00CC6F1E /* Project object */; 251 | } 252 | -------------------------------------------------------------------------------- /osx/Injector.xcodeproj/project.xcworkspace/xcshareddata/Injector.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | 6740BFF3-D636-45E1-80BF-B7D1AC6B8171 9 | IDESourceControlProjectName 10 | Injector 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 781D6DCF55A0213C9EFB7DB5454D0F4D4242F036 14 | https://github.com/GoatHunter/goatnative-inject 15 | 16 | IDESourceControlProjectPath 17 | osx/Injector.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 781D6DCF55A0213C9EFB7DB5454D0F4D4242F036 21 | ../../.. 22 | 23 | IDESourceControlProjectURL 24 | https://github.com/GoatHunter/goatnative-inject 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 781D6DCF55A0213C9EFB7DB5454D0F4D4242F036 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 781D6DCF55A0213C9EFB7DB5454D0F4D4242F036 36 | IDESourceControlWCCName 37 | Injector 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /osx/Injector.xcodeproj/xcuserdata/max.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 20 | 21 | 22 | 24 | 36 | 37 | 50 | 51 | 64 | 65 | 66 | 67 | 68 | 70 | 82 | 83 | 96 | 97 | 110 | 111 | 124 | 125 | 138 | 139 | 152 | 153 | 166 | 167 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | -------------------------------------------------------------------------------- /osx/Injector.xcodeproj/xcuserdata/max.xcuserdatad/xcschemes/Injector.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /osx/Injector.xcodeproj/xcuserdata/max.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Injector.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 5010FA8E1A6AA91F00CC6F1E 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /win/inject/inject.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.30723.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "inject", "inject.vcxproj", "{2AEB2FA3-B364-4F48-9468-3BB18DA7DEE7}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Win32 = Debug|Win32 11 | Release|Win32 = Release|Win32 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {2AEB2FA3-B364-4F48-9468-3BB18DA7DEE7}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {2AEB2FA3-B364-4F48-9468-3BB18DA7DEE7}.Debug|Win32.Build.0 = Debug|Win32 16 | {2AEB2FA3-B364-4F48-9468-3BB18DA7DEE7}.Release|Win32.ActiveCfg = Release|Win32 17 | {2AEB2FA3-B364-4F48-9468-3BB18DA7DEE7}.Release|Win32.Build.0 = Release|Win32 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /win/inject/inject.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {2AEB2FA3-B364-4F48-9468-3BB18DA7DEE7} 15 | Win32Proj 16 | inject 17 | 18 | 19 | 20 | Application 21 | true 22 | v120 23 | Unicode 24 | 25 | 26 | Application 27 | false 28 | v120 29 | true 30 | Unicode 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | true 44 | 45 | 46 | false 47 | 48 | 49 | 50 | 51 | 52 | Level3 53 | Disabled 54 | WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 55 | true 56 | 57 | 58 | Console 59 | true 60 | 61 | 62 | 63 | 64 | Level3 65 | 66 | 67 | MaxSpeed 68 | true 69 | true 70 | WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions) 71 | true 72 | 73 | 74 | Console 75 | true 76 | true 77 | true 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | --------------------------------------------------------------------------------