1 //----------------------------------------------------------------------------- 2 // Project : SDK Core 3 // 4 // Category : SDK Core Interfaces 5 // Filename : pluginterfaces/base/ipluginbase.h 6 // Created by : Steinberg, 01/2004 7 // Description : Basic Plug-in Interfaces 8 // 9 //----------------------------------------------------------------------------- 10 // This file is part of a Steinberg SDK. It is subject to the license terms 11 // in the LICENSE file found in the top-level directory of this distribution 12 // and at www.steinberg.net/sdklicenses. 13 // No part of the SDK, including this file, may be copied, modified, propagated, 14 // or distributed except according to the terms contained in the LICENSE file. 15 //----------------------------------------------------------------------------- 16 17 #pragma once 18 19 #include "funknown.h" 20 #include "fstrdefs.h" 21 22 namespace Steinberg { 23 24 //------------------------------------------------------------------------ 25 /** Basic interface to a Plug-in component. 26 \ingroup pluginBase 27 - [plug imp] 28 - initialize/terminate the Plug-in component 29 30 The host uses this interface to initialize and to terminate the Plug-in component. 31 The context that is passed to the initialize method contains any interface to the 32 host that the Plug-in will need to work. These interfaces can vary from category to category. 33 A list of supported host context interfaces should be included in the documentation 34 of a specific category. */ 35 //------------------------------------------------------------------------ 36 class IPluginBase: public FUnknown 37 { 38 public: 39 //------------------------------------------------------------------------ 40 /** The host passes a number of interfaces as context to initialize the Plug-in class. 41 @note Extensive memory allocations etc. should be performed in this method rather than in the class' constructor! 42 If the method does NOT return kResultOk, the object is released immediately. In this case terminate is not called! */ 43 virtual tresult PLUGIN_API initialize (FUnknown* context) = 0; 44 45 /** This function is called before the Plug-in is unloaded and can be used for 46 cleanups. You have to release all references to any host application interfaces. */ 47 virtual tresult PLUGIN_API terminate () = 0; 48 49 //------------------------------------------------------------------------ 50 static const FUID iid; 51 }; 52 53 DECLARE_CLASS_IID (IPluginBase, 0x22888DDB, 0x156E45AE, 0x8358B348, 0x08190625) 54 55 56 //------------------------------------------------------------------------ 57 /** Basic Information about the class factory of the Plug-in. 58 \ingroup pluginBase 59 */ 60 //------------------------------------------------------------------------ 61 struct PFactoryInfo 62 { 63 //------------------------------------------------------------------------ 64 enum FactoryFlags 65 { 66 kNoFlags = 0, ///< Nothing 67 kClassesDiscardable = 1 << 0, ///< The number of exported classes can change each time the Module is loaded. If this flag is set, the host does not cache class information. This leads to a longer startup time because the host always has to load the Module to get the current class information. 68 kLicenseCheck = 1 << 1, ///< Class IDs of components are interpreted as Syncrosoft-License (LICENCE_UID). Loaded in a Steinberg host, the module will not be loaded when the license is not valid 69 kComponentNonDiscardable = 1 << 3, ///< Component won't be unloaded until process exit 70 kUnicode = 1 << 4 ///< Components have entirely unicode encoded strings. (True for VST 3 Plug-ins so far) 71 }; 72 73 enum 74 { 75 kURLSize = 256, 76 kEmailSize = 128, 77 kNameSize = 64 78 }; 79 80 //------------------------------------------------------------------------ 81 char8 vendor[kNameSize]; ///< e.g. "Steinberg Media Technologies" 82 char8 url[kURLSize]; ///< e.g. "http://www.steinberg.de" 83 char8 email[kEmailSize]; ///< e.g. "info@steinberg.de" 84 int32 flags; ///< (see above) 85 //------------------------------------------------------------------------ PFactoryInfoPFactoryInfo86 PFactoryInfo (const char8* _vendor, const char8* _url, const char8* _email, int32 _flags) 87 { 88 strncpy8 (vendor, _vendor, kNameSize); 89 strncpy8 (url, _url, kURLSize); 90 strncpy8 (email, _email, kEmailSize); 91 flags = _flags; 92 #ifdef UNICODE 93 flags |= kUnicode; 94 #endif 95 } 96 #if SMTG_CPP11 PFactoryInfoPFactoryInfo97 constexpr PFactoryInfo () : vendor (), url (), email (), flags () {} 98 #else PFactoryInfoPFactoryInfo99 PFactoryInfo () { memset (this, 0, sizeof (PFactoryInfo)); } 100 #endif 101 }; 102 103 //------------------------------------------------------------------------ 104 /** Basic Information about a class provided by the Plug-in. 105 \ingroup pluginBase 106 */ 107 //------------------------------------------------------------------------ 108 struct PClassInfo 109 { 110 //------------------------------------------------------------------------ 111 enum ClassCardinality 112 { 113 kManyInstances = 0x7FFFFFFF 114 }; 115 116 enum 117 { 118 kCategorySize = 32, 119 kNameSize = 64 120 }; 121 //------------------------------------------------------------------------ 122 TUID cid; ///< Class ID 16 Byte class GUID 123 int32 cardinality; ///< cardinality of the class, set to kManyInstances (see \ref ClassCardinality) 124 char8 category[kCategorySize]; ///< class category, host uses this to categorize interfaces 125 char8 name[kNameSize]; ///< class name, visible to the user 126 //------------------------------------------------------------------------ 127 PClassInfoPClassInfo128 PClassInfo (const TUID _cid, int32 _cardinality, const char8* _category, const char8* _name) 129 { 130 memset (this, 0, sizeof (PClassInfo)); 131 memcpy (cid, _cid, sizeof (TUID)); 132 if (_category) 133 strncpy8 (category, _category, kCategorySize); 134 if (_name) 135 strncpy8 (name, _name, kNameSize); 136 cardinality = _cardinality; 137 } 138 #if SMTG_CPP11 PClassInfoPClassInfo139 constexpr PClassInfo () : cid (), cardinality (), category (), name () {} 140 #else PClassInfoPClassInfo141 PClassInfo () { memset (this, 0, sizeof (PClassInfo)); } 142 #endif 143 }; 144 145 146 //------------------------------------------------------------------------ 147 // IPluginFactory interface declaration 148 //------------------------------------------------------------------------ 149 /** Class factory that any Plug-in defines for creating class instances. 150 \ingroup pluginBase 151 - [plug imp] 152 153 From the host's point of view a Plug-in module is a factory which can create 154 a certain kind of object(s). The interface IPluginFactory provides methods 155 to get information about the classes exported by the Plug-in and a 156 mechanism to create instances of these classes (that usually define the IPluginBase interface). 157 158 <b> An implementation is provided in public.sdk/source/common/pluginfactory.cpp </b> 159 \see GetPluginFactory 160 */ 161 //------------------------------------------------------------------------ 162 class IPluginFactory : public FUnknown 163 { 164 public: 165 //------------------------------------------------------------------------ 166 /** Fill a PFactoryInfo structure with information about the Plug-in vendor. */ 167 virtual tresult PLUGIN_API getFactoryInfo (PFactoryInfo* info) = 0; 168 169 /** Returns the number of exported classes by this factory. 170 If you are using the CPluginFactory implementation provided by the SDK, it returns the number of classes you registered with CPluginFactory::registerClass. */ 171 virtual int32 PLUGIN_API countClasses () = 0; 172 173 /** Fill a PClassInfo structure with information about the class at the specified index. */ 174 virtual tresult PLUGIN_API getClassInfo (int32 index, PClassInfo* info) = 0; 175 176 /** Create a new class instance. */ 177 virtual tresult PLUGIN_API createInstance (FIDString cid, FIDString _iid, void** obj) = 0; 178 179 //------------------------------------------------------------------------ 180 static const FUID iid; 181 }; 182 183 DECLARE_CLASS_IID (IPluginFactory, 0x7A4D811C, 0x52114A1F, 0xAED9D2EE, 0x0B43BF9F) 184 185 186 //------------------------------------------------------------------------ 187 /** Version 2 of Basic Information about a class provided by the Plug-in. 188 \ingroup pluginBase 189 */ 190 //------------------------------------------------------------------------ 191 struct PClassInfo2 192 { 193 //------------------------------------------------------------------------ 194 TUID cid; ///< Class ID 16 Byte class GUID 195 int32 cardinality; ///< cardinality of the class, set to kManyInstances (see \ref ClassCardinality) 196 char8 category[PClassInfo::kCategorySize]; ///< class category, host uses this to categorize interfaces 197 char8 name[PClassInfo::kNameSize]; ///< class name, visible to the user 198 199 enum { 200 kVendorSize = 64, 201 kVersionSize = 64, 202 kSubCategoriesSize = 128 203 }; 204 205 uint32 classFlags; ///< flags used for a specific category, must be defined where category is defined 206 char8 subCategories[kSubCategoriesSize]; ///< module specific subcategories, can be more than one, logically added by the \c OR operator 207 char8 vendor[kVendorSize]; ///< overwrite vendor information from factory info 208 char8 version[kVersionSize]; ///< Version string (e.g. "1.0.0.512" with Major.Minor.Subversion.Build) 209 char8 sdkVersion[kVersionSize]; ///< SDK version used to build this class (e.g. "VST 3.0") 210 211 //------------------------------------------------------------------------ 212 PClassInfo2PClassInfo2213 PClassInfo2 (const TUID _cid, int32 _cardinality, const char8* _category, const char8* _name, 214 int32 _classFlags, const char8* _subCategories, const char8* _vendor, const char8* _version, 215 const char8* _sdkVersion) 216 { 217 memset (this, 0, sizeof (PClassInfo2)); 218 memcpy (cid, _cid, sizeof (TUID)); 219 cardinality = _cardinality; 220 if (_category) 221 strncpy8 (category, _category, PClassInfo::kCategorySize); 222 if (_name) 223 strncpy8 (name, _name, PClassInfo::kNameSize); 224 classFlags = static_cast<uint32> (_classFlags); 225 if (_subCategories) 226 strncpy8 (subCategories, _subCategories, kSubCategoriesSize); 227 if (_vendor) 228 strncpy8 (vendor, _vendor, kVendorSize); 229 if (_version) 230 strncpy8 (version, _version, kVersionSize); 231 if (_sdkVersion) 232 strncpy8 (sdkVersion, _sdkVersion, kVersionSize); 233 } 234 #if SMTG_CPP11 PClassInfo2PClassInfo2235 constexpr PClassInfo2 () 236 : cid () 237 , cardinality () 238 , category () 239 , name () 240 , classFlags () 241 , subCategories () 242 , vendor () 243 , version () 244 , sdkVersion () 245 { 246 } 247 #else PClassInfo2PClassInfo2248 PClassInfo2 () { memset (this, 0, sizeof (PClassInfo2)); } 249 #endif 250 }; 251 252 //------------------------------------------------------------------------ 253 // IPluginFactory2 interface declaration 254 //------------------------------------------------------------------------ 255 /** Version 2 of class factory supporting PClassInfo2. 256 \ingroup pluginBase 257 \copydoc IPluginFactory 258 */ 259 //------------------------------------------------------------------------ 260 class IPluginFactory2 : public IPluginFactory 261 { 262 public: 263 //------------------------------------------------------------------------ 264 /** Returns the class info (version 2) for a given index. */ 265 virtual tresult PLUGIN_API getClassInfo2 (int32 index, PClassInfo2* info) = 0; 266 267 //------------------------------------------------------------------------ 268 static const FUID iid; 269 }; 270 DECLARE_CLASS_IID (IPluginFactory2, 0x0007B650, 0xF24B4C0B, 0xA464EDB9, 0xF00B2ABB) 271 272 273 //------------------------------------------------------------------------ 274 /** Unicode Version of Basic Information about a class provided by the Plug-in */ 275 //------------------------------------------------------------------------ 276 struct PClassInfoW 277 { 278 //------------------------------------------------------------------------ 279 TUID cid; ///< see \ref PClassInfo 280 int32 cardinality; ///< see \ref PClassInfo 281 char8 category[PClassInfo::kCategorySize]; ///< see \ref PClassInfo 282 char16 name[PClassInfo::kNameSize]; ///< see \ref PClassInfo 283 284 enum { 285 kVendorSize = 64, 286 kVersionSize = 64, 287 kSubCategoriesSize = 128 288 }; 289 290 uint32 classFlags; ///< flags used for a specific category, must be defined where category is defined 291 char8 subCategories[kSubCategoriesSize];///< module specific subcategories, can be more than one, logically added by the \c OR operator 292 char16 vendor[kVendorSize]; ///< overwrite vendor information from factory info 293 char16 version[kVersionSize]; ///< Version string (e.g. "1.0.0.512" with Major.Minor.Subversion.Build) 294 char16 sdkVersion[kVersionSize]; ///< SDK version used to build this class (e.g. "VST 3.0") 295 296 //------------------------------------------------------------------------ PClassInfoWPClassInfoW297 PClassInfoW (const TUID _cid, int32 _cardinality, const char8* _category, const char16* _name, 298 int32 _classFlags, const char8* _subCategories, const char16* _vendor, const char16* _version, 299 const char16* _sdkVersion) 300 { 301 memset (this, 0, sizeof (PClassInfoW)); 302 memcpy (cid, _cid, sizeof (TUID)); 303 cardinality = _cardinality; 304 if (_category) 305 strncpy8 (category, _category, PClassInfo::kCategorySize); 306 if (_name) 307 strncpy16 (name, _name, PClassInfo::kNameSize); 308 classFlags = static_cast<uint32> (_classFlags); 309 if (_subCategories) 310 strncpy8 (subCategories, _subCategories, kSubCategoriesSize); 311 if (_vendor) 312 strncpy16 (vendor, _vendor, kVendorSize); 313 if (_version) 314 strncpy16 (version, _version, kVersionSize); 315 if (_sdkVersion) 316 strncpy16 (sdkVersion, _sdkVersion, kVersionSize); 317 } 318 #if SMTG_CPP11 PClassInfoWPClassInfoW319 constexpr PClassInfoW () 320 : cid () 321 , cardinality () 322 , category () 323 , name () 324 , classFlags () 325 , subCategories () 326 , vendor () 327 , version () 328 , sdkVersion () 329 { 330 } 331 #else PClassInfoWPClassInfoW332 PClassInfoW () { memset (this, 0, sizeof (PClassInfoW)); } 333 #endif 334 fromAsciiPClassInfoW335 void fromAscii (const PClassInfo2& ci2) 336 { 337 memcpy (cid, ci2.cid, sizeof (TUID)); 338 cardinality = ci2.cardinality; 339 strncpy8 (category, ci2.category, PClassInfo::kCategorySize); 340 str8ToStr16 (name, ci2.name, PClassInfo::kNameSize); 341 classFlags = ci2.classFlags; 342 strncpy8 (subCategories, ci2.subCategories, kSubCategoriesSize); 343 344 str8ToStr16 (vendor, ci2.vendor, kVendorSize); 345 str8ToStr16 (version, ci2.version, kVersionSize); 346 str8ToStr16 (sdkVersion, ci2.sdkVersion, kVersionSize); 347 } 348 }; 349 350 351 //------------------------------------------------------------------------ 352 // IPluginFactory3 interface declaration 353 //------------------------------------------------------------------------ 354 /** Version 3 of class factory supporting PClassInfoW. 355 \ingroup pluginBase 356 \copydoc IPluginFactory 357 */ 358 //------------------------------------------------------------------------ 359 class IPluginFactory3 : public IPluginFactory2 360 { 361 public: 362 //------------------------------------------------------------------------ 363 /** Returns the unicode class info for a given index. */ 364 virtual tresult PLUGIN_API getClassInfoUnicode (int32 index, PClassInfoW* info) = 0; 365 366 /** Receives information about host*/ 367 virtual tresult PLUGIN_API setHostContext (FUnknown* context) = 0; 368 369 //------------------------------------------------------------------------ 370 static const FUID iid; 371 }; 372 DECLARE_CLASS_IID (IPluginFactory3, 0x4555A2AB, 0xC1234E57, 0x9B122910, 0x36878931) 373 //------------------------------------------------------------------------ 374 } // namespace Steinberg 375 376 377 //------------------------------------------------------------------------ 378 #define LICENCE_UID(l1, l2, l3, l4) \ 379 { \ 380 (int8)((l1 & 0xFF000000) >> 24), (int8)((l1 & 0x00FF0000) >> 16), \ 381 (int8)((l1 & 0x0000FF00) >> 8), (int8)((l1 & 0x000000FF) ), \ 382 (int8)((l2 & 0xFF000000) >> 24), (int8)((l2 & 0x00FF0000) >> 16), \ 383 (int8)((l2 & 0x0000FF00) >> 8), (int8)((l2 & 0x000000FF) ), \ 384 (int8)((l3 & 0xFF000000) >> 24), (int8)((l3 & 0x00FF0000) >> 16), \ 385 (int8)((l3 & 0x0000FF00) >> 8), (int8)((l3 & 0x000000FF) ), \ 386 (int8)((l4 & 0xFF000000) >> 24), (int8)((l4 & 0x00FF0000) >> 16), \ 387 (int8)((l4 & 0x0000FF00) >> 8), (int8)((l4 & 0x000000FF) ) \ 388 } 389 390 391 //------------------------------------------------------------------------ 392 // GetPluginFactory 393 //------------------------------------------------------------------------ 394 /** Plug-in entry point. 395 \ingroup pluginBase 396 Any Plug-in must define and export this function. \n 397 A typical implementation of GetPluginFactory looks like this 398 \code 399 IPluginFactory* PLUGIN_API GetPluginFactory () 400 { 401 if (!gPluginFactory) 402 { 403 static PFactoryInfo factoryInfo = 404 { 405 "My Company Name", 406 "http://www.mywebpage.com", 407 "mailto:myemail@address.com", 408 PFactoryInfo::kNoFlags 409 }; 410 411 gPluginFactory = new CPluginFactory (factoryInfo); 412 413 static PClassInfo componentClass = 414 { 415 INLINE_UID (0x00000000, 0x00000000, 0x00000000, 0x00000000), // replace by a valid uid 416 1, 417 "Service", // category 418 "Name" 419 }; 420 421 gPluginFactory->registerClass (&componentClass, MyComponentClass::newInstance); 422 } 423 else 424 gPluginFactory->addRef (); 425 426 return gPluginFactory; 427 } 428 \endcode 429 \see \ref loadPlugin 430 */ 431 //------------------------------------------------------------------------ 432 extern "C" 433 { 434 Steinberg::IPluginFactory* PLUGIN_API GetPluginFactory (); 435 typedef Steinberg::IPluginFactory* (PLUGIN_API *GetFactoryProc) (); 436 } 437