mirror of
https://github.com/VCMP-SqMod/SqMod.git
synced 2025-06-19 16:47:14 +02:00
Implemented the module system.
This commit is contained in:
@ -229,26 +229,33 @@ bool Core::Init()
|
||||
{
|
||||
// Get the file path as a string
|
||||
String path(itr->pItem);
|
||||
// See if it wasn't already loaded
|
||||
if (m_Scripts.find(path) != m_Scripts.end())
|
||||
// See if the specified script path is valid
|
||||
if (path.empty())
|
||||
{
|
||||
LogWrn("Script was already loaded: %s", path.c_str());
|
||||
// Simply ignore it
|
||||
continue;
|
||||
}
|
||||
// See if it wasn't already loaded
|
||||
else if (m_Scripts.find(path) != m_Scripts.end())
|
||||
{
|
||||
LogWrn("Script was specified before: %s", path.c_str());
|
||||
// No point in loading it again
|
||||
continue;
|
||||
}
|
||||
// Attempt to compile it
|
||||
else if (!Compile(path))
|
||||
// Create a new script container and insert it into the script pool
|
||||
std::pair< Scripts::iterator, bool > res = m_Scripts.insert(Scripts::value_type(path, Script(m_VM)));
|
||||
// We don't compile the scripts yet. We just store their path and prepare the objects.
|
||||
if (!res.second)
|
||||
{
|
||||
// Plug-in shouldn't load
|
||||
LogErr("Unable to queue script: %s", path.c_str());
|
||||
// Drop all previous scripts
|
||||
m_Scripts.clear();
|
||||
// Failed to compile the specified script
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
LogScs("Successfully compiled script: %s", path.c_str());
|
||||
}
|
||||
}
|
||||
// See if any script could be compiled
|
||||
if (m_Scripts.empty())
|
||||
if (m_Scripts.empty() && !conf.GetBoolValue("Config", "EmptyInit", false))
|
||||
{
|
||||
LogErr("No scripts compiled. No reason to load the plug-in");
|
||||
// No point in loading the plug-in
|
||||
@ -303,25 +310,27 @@ bool Core::Load()
|
||||
{
|
||||
// Are there any scripts to execute?
|
||||
if (cLogErr(m_Scripts.empty(), "No scripts to execute. Plug-in has no purpose"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
LogDbg("Signaling outside plugins to register their API");
|
||||
// Signal outside plugins to do their monkey business
|
||||
_Func->SendCustomCommand(0xDABBAD00, "");
|
||||
LogDbg("Attempting to execute the specified scripts");
|
||||
// Go through each loaded script
|
||||
// Go through each specified script
|
||||
for (Scripts::iterator itr = m_Scripts.begin(); itr != m_Scripts.end(); ++itr)
|
||||
{
|
||||
// Attempt to load and compile the script file
|
||||
itr->second.CompileFile(itr->first);
|
||||
// See if any compile time error occurred during compilation
|
||||
if (Error::Occurred(m_VM))
|
||||
return false; /* Failed to load properly */
|
||||
// Attempt to execute the script
|
||||
itr->second.Run();
|
||||
// See if the executed script had any errors
|
||||
if (Error::Occurred(m_VM))
|
||||
{
|
||||
// Failed to execute scripts
|
||||
return false;
|
||||
}
|
||||
return false; /* Failed to load properly */
|
||||
else
|
||||
{
|
||||
LogScs("Successfully executed script: %s", itr->first.c_str());
|
||||
}
|
||||
}
|
||||
// Successfully loaded
|
||||
return true;
|
||||
@ -363,42 +372,6 @@ void Core::Terminate()
|
||||
}
|
||||
}
|
||||
|
||||
bool Core::Compile(const string & name)
|
||||
{
|
||||
// See if the specified script path is valid
|
||||
if (name.empty())
|
||||
{
|
||||
LogErr("Cannot compile script without a valid name");
|
||||
// Failed to compile the specified script
|
||||
return false;
|
||||
}
|
||||
// Create a new script container and insert it into the script pool
|
||||
std::pair< Scripts::iterator, bool > res = m_Scripts.insert(Scripts::value_type(name, Script(m_VM)));
|
||||
// See if the script container could be created and inserted
|
||||
if (res.second)
|
||||
{
|
||||
// Attempt to load and compile the specified script file
|
||||
res.first->second.CompileFile(name);
|
||||
// See if any compile time error occurred in the compiled script
|
||||
if (Error::Occurred(m_VM))
|
||||
{
|
||||
// Release the script container
|
||||
m_Scripts.erase(res.first);
|
||||
// Failed to compile the specified script
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// Failed to create the script container
|
||||
else
|
||||
{
|
||||
LogErr("Unable to queue script: %s", name.c_str());
|
||||
// Failed to compile the specified script
|
||||
return false;
|
||||
}
|
||||
// At this point everything went as it should
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CSStr Core::GetOption(const String & name) const
|
||||
{
|
||||
|
@ -499,11 +499,6 @@ public:
|
||||
|
||||
protected:
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Compile the specified file as a script.
|
||||
*/
|
||||
bool Compile(const string & name);
|
||||
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Script output handlers.
|
||||
*/
|
||||
|
227
source/Exports.cpp
Normal file
227
source/Exports.cpp
Normal file
@ -0,0 +1,227 @@
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include "Core.hpp"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
#include <sqstdio.h>
|
||||
#include <sqstdblob.h>
|
||||
#include <sqstdstring.h>
|
||||
#include <sq_mod.h>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static SQAPI g_SqAPI;
|
||||
static SQEXPORTS g_SqExports;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static HSQAPI GetSquirrelAPI()
|
||||
{
|
||||
return &g_SqAPI;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
static HSQUIRRELVM GetSquirrelVM()
|
||||
{
|
||||
if (_Core)
|
||||
return _Core->GetVM();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void InitExports()
|
||||
{
|
||||
static HSQEXPORTS sqexports = &g_SqExports;
|
||||
|
||||
// Assign the functions that should be exported
|
||||
g_SqExports.uStructSize = sizeof(SQEXPORTS);
|
||||
g_SqExports.GetSquirrelAPI = GetSquirrelAPI;
|
||||
g_SqExports.GetSquirrelVM = GetSquirrelVM;
|
||||
// Export them to the server
|
||||
_Func->ExportFunctions(_Info->nPluginId, (void **)(&sqexports), sizeof(SQEXPORTS));
|
||||
/*vm*/
|
||||
g_SqAPI.open = sq_open;
|
||||
g_SqAPI.newthread = sq_newthread;
|
||||
g_SqAPI.seterrorhandler = sq_seterrorhandler;
|
||||
g_SqAPI.close = sq_close;
|
||||
g_SqAPI.setforeignptr = sq_setforeignptr;
|
||||
g_SqAPI.getforeignptr = sq_getforeignptr;
|
||||
g_SqAPI.setsharedforeignptr = sq_setsharedforeignptr;
|
||||
g_SqAPI.getsharedforeignptr = sq_getsharedforeignptr;
|
||||
g_SqAPI.setvmreleasehook = sq_setvmreleasehook;
|
||||
g_SqAPI.getvmreleasehook = sq_getvmreleasehook;
|
||||
g_SqAPI.setsharedreleasehook = sq_setsharedreleasehook;
|
||||
g_SqAPI.getsharedreleasehook = sq_getsharedreleasehook;
|
||||
g_SqAPI.setprintfunc = sq_setprintfunc;
|
||||
g_SqAPI.getprintfunc = sq_getprintfunc;
|
||||
g_SqAPI.geterrorfunc = sq_geterrorfunc;
|
||||
g_SqAPI.suspendvm = sq_suspendvm;
|
||||
g_SqAPI.wakeupvm = sq_wakeupvm;
|
||||
g_SqAPI.getvmstate = sq_getvmstate;
|
||||
g_SqAPI.getversion = sq_getversion;
|
||||
|
||||
/*compiler*/
|
||||
g_SqAPI.compile = sq_compile;
|
||||
g_SqAPI.compilebuffer = sq_compilebuffer;
|
||||
g_SqAPI.enabledebuginfo = sq_enabledebuginfo;
|
||||
g_SqAPI.notifyallexceptions = sq_notifyallexceptions;
|
||||
g_SqAPI.setcompilererrorhandler = sq_setcompilererrorhandler;
|
||||
|
||||
/*stack operations*/
|
||||
g_SqAPI.push = sq_push;
|
||||
g_SqAPI.pop = sq_pop;
|
||||
g_SqAPI.poptop = sq_poptop;
|
||||
g_SqAPI.remove = sq_remove;
|
||||
g_SqAPI.gettop = sq_gettop;
|
||||
g_SqAPI.settop = sq_settop;
|
||||
g_SqAPI.reservestack = sq_reservestack;
|
||||
g_SqAPI.cmp = sq_cmp;
|
||||
g_SqAPI.move = sq_move;
|
||||
|
||||
/*object creation handling*/
|
||||
g_SqAPI.newuserdata = sq_newuserdata;
|
||||
g_SqAPI.newtable = sq_newtable;
|
||||
g_SqAPI.newtableex = sq_newtableex;
|
||||
g_SqAPI.newarray = sq_newarray;
|
||||
g_SqAPI.newclosure = sq_newclosure;
|
||||
g_SqAPI.setparamscheck = sq_setparamscheck;
|
||||
g_SqAPI.bindenv = sq_bindenv;
|
||||
g_SqAPI.setclosureroot = sq_setclosureroot;
|
||||
g_SqAPI.getclosureroot = sq_getclosureroot;
|
||||
g_SqAPI.pushstring = sq_pushstring;
|
||||
g_SqAPI.pushfloat = sq_pushfloat;
|
||||
g_SqAPI.pushinteger = sq_pushinteger;
|
||||
g_SqAPI.pushbool = sq_pushbool;
|
||||
g_SqAPI.pushuserpointer = sq_pushuserpointer;
|
||||
g_SqAPI.pushnull = sq_pushnull;
|
||||
g_SqAPI.pushthread = sq_pushthread;
|
||||
g_SqAPI.gettype = sq_gettype;
|
||||
g_SqAPI.typeof_ = sq_typeof;
|
||||
g_SqAPI.getsize = sq_getsize;
|
||||
g_SqAPI.gethash = sq_gethash;
|
||||
g_SqAPI.getbase = sq_getbase;
|
||||
g_SqAPI.instanceof = sq_instanceof;
|
||||
g_SqAPI.tostring = sq_tostring;
|
||||
g_SqAPI.tobool = sq_tobool;
|
||||
g_SqAPI.getstring = sq_getstring;
|
||||
g_SqAPI.getinteger = sq_getinteger;
|
||||
g_SqAPI.getfloat = sq_getfloat;
|
||||
g_SqAPI.getbool = sq_getbool;
|
||||
g_SqAPI.getthread = sq_getthread;
|
||||
g_SqAPI.getuserpointer = sq_getuserpointer;
|
||||
g_SqAPI.getuserdata = sq_getuserdata;
|
||||
g_SqAPI.settypetag = sq_settypetag;
|
||||
g_SqAPI.gettypetag = sq_gettypetag;
|
||||
g_SqAPI.setreleasehook = sq_setreleasehook;
|
||||
g_SqAPI.getreleasehook = sq_getreleasehook;
|
||||
g_SqAPI.getscratchpad = sq_getscratchpad;
|
||||
g_SqAPI.getfunctioninfo = sq_getfunctioninfo;
|
||||
g_SqAPI.getclosureinfo = sq_getclosureinfo;
|
||||
g_SqAPI.getclosurename = sq_getclosurename;
|
||||
g_SqAPI.setnativeclosurename = sq_setnativeclosurename;
|
||||
g_SqAPI.setinstanceup = sq_setinstanceup;
|
||||
g_SqAPI.getinstanceup = sq_getinstanceup;
|
||||
g_SqAPI.setclassudsize = sq_setclassudsize;
|
||||
g_SqAPI.newclass = sq_newclass;
|
||||
g_SqAPI.createinstance = sq_createinstance;
|
||||
g_SqAPI.setattributes = sq_setattributes;
|
||||
g_SqAPI.getattributes = sq_getattributes;
|
||||
g_SqAPI.getclass = sq_getclass;
|
||||
g_SqAPI.weakref = sq_weakref;
|
||||
g_SqAPI.getdefaultdelegate = sq_getdefaultdelegate;
|
||||
g_SqAPI.getmemberhandle = sq_getmemberhandle;
|
||||
g_SqAPI.getbyhandle = sq_getbyhandle;
|
||||
g_SqAPI.setbyhandle = sq_setbyhandle;
|
||||
|
||||
/*object manipulation*/
|
||||
g_SqAPI.pushroottable = sq_pushroottable;
|
||||
g_SqAPI.pushregistrytable = sq_pushregistrytable;
|
||||
g_SqAPI.pushconsttable = sq_pushconsttable;
|
||||
g_SqAPI.setroottable = sq_setroottable;
|
||||
g_SqAPI.setconsttable = sq_setconsttable;
|
||||
g_SqAPI.newslot = sq_newslot;
|
||||
g_SqAPI.deleteslot = sq_deleteslot;
|
||||
g_SqAPI.set = sq_set;
|
||||
g_SqAPI.get = sq_get;
|
||||
g_SqAPI.rawget = sq_rawget;
|
||||
g_SqAPI.rawset = sq_rawset;
|
||||
g_SqAPI.rawdeleteslot = sq_rawdeleteslot;
|
||||
g_SqAPI.newmember = sq_newmember;
|
||||
g_SqAPI.rawnewmember = sq_rawnewmember;
|
||||
g_SqAPI.arrayappend = sq_arrayappend;
|
||||
g_SqAPI.arraypop = sq_arraypop;
|
||||
g_SqAPI.arrayresize = sq_arrayresize;
|
||||
g_SqAPI.arrayreverse = sq_arrayreverse;
|
||||
g_SqAPI.arrayremove = sq_arrayremove;
|
||||
g_SqAPI.arrayinsert = sq_arrayinsert;
|
||||
g_SqAPI.setdelegate = sq_setdelegate;
|
||||
g_SqAPI.getdelegate = sq_getdelegate;
|
||||
g_SqAPI.clone = sq_clone;
|
||||
g_SqAPI.setfreevariable = sq_setfreevariable;
|
||||
g_SqAPI.next = sq_next;
|
||||
g_SqAPI.getweakrefval = sq_getweakrefval;
|
||||
g_SqAPI.clear = sq_clear;
|
||||
|
||||
/*calls*/
|
||||
g_SqAPI.call = sq_call;
|
||||
g_SqAPI.resume = sq_resume;
|
||||
g_SqAPI.getlocal = sq_getlocal;
|
||||
g_SqAPI.getcallee = sq_getcallee;
|
||||
g_SqAPI.getfreevariable = sq_getfreevariable;
|
||||
g_SqAPI.throwerror = sq_throwerror;
|
||||
g_SqAPI.throwobject = sq_throwobject;
|
||||
g_SqAPI.reseterror = sq_reseterror;
|
||||
g_SqAPI.getlasterror = sq_getlasterror;
|
||||
|
||||
/*raw object handling*/
|
||||
g_SqAPI.getstackobj = sq_getstackobj;
|
||||
g_SqAPI.pushobject = sq_pushobject;
|
||||
g_SqAPI.addref = sq_addref;
|
||||
g_SqAPI.release = sq_release;
|
||||
g_SqAPI.getrefcount = sq_getrefcount;
|
||||
g_SqAPI.resetobject = sq_resetobject;
|
||||
g_SqAPI.objtostring = sq_objtostring;
|
||||
g_SqAPI.objtobool = sq_objtobool;
|
||||
g_SqAPI.objtointeger = sq_objtointeger;
|
||||
g_SqAPI.objtofloat = sq_objtofloat;
|
||||
g_SqAPI.objtouserpointer = sq_objtouserpointer;
|
||||
g_SqAPI.getobjtypetag = sq_getobjtypetag;
|
||||
g_SqAPI.getvmrefcount = sq_getvmrefcount;
|
||||
|
||||
/*GC*/
|
||||
g_SqAPI.collectgarbage = sq_collectgarbage;
|
||||
g_SqAPI.resurrectunreachable = sq_resurrectunreachable;
|
||||
|
||||
/*serialization*/
|
||||
g_SqAPI.writeclosure = sq_writeclosure;
|
||||
g_SqAPI.readclosure = sq_readclosure;
|
||||
|
||||
/*mem allocation*/
|
||||
g_SqAPI.malloc = sq_malloc;
|
||||
g_SqAPI.realloc = sq_realloc;
|
||||
g_SqAPI.free = sq_free;
|
||||
|
||||
/*debug*/
|
||||
g_SqAPI.stackinfos = sq_stackinfos;
|
||||
g_SqAPI.setdebughook = sq_setdebughook;
|
||||
g_SqAPI.setnativedebughook = sq_setnativedebughook;
|
||||
|
||||
/*compiler helpers*/
|
||||
g_SqAPI.loadfile = sqstd_loadfile;
|
||||
g_SqAPI.dofile = sqstd_dofile;
|
||||
g_SqAPI.writeclosuretofile = sqstd_writeclosuretofile;
|
||||
|
||||
/*blob*/
|
||||
g_SqAPI.createblob = sqstd_createblob;
|
||||
g_SqAPI.getblob = sqstd_getblob;
|
||||
g_SqAPI.getblobsize = sqstd_getblobsize;
|
||||
|
||||
/*string*/
|
||||
g_SqAPI.format = sqstd_format;
|
||||
}
|
||||
|
||||
} // Namespace:: SqMod
|
@ -10,6 +10,11 @@
|
||||
#include <winsock2.h>
|
||||
#endif // _WIN32
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
namespace SqMod {
|
||||
extern void InitExports();
|
||||
} // Namespace:: SqMod
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
using namespace SqMod;
|
||||
|
||||
@ -17,6 +22,29 @@ using namespace SqMod;
|
||||
void BindCallbacks();
|
||||
void UnbindCallbacks();
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void DestroyComponents()
|
||||
{
|
||||
// Destroy command component
|
||||
if (_Cmd)
|
||||
{
|
||||
delete _Cmd;
|
||||
_Cmd = NULL;
|
||||
}
|
||||
// Destroy core component
|
||||
if (_Core)
|
||||
{
|
||||
delete _Core;
|
||||
_Core = NULL;
|
||||
}
|
||||
// Destroy logger component
|
||||
if (_Log)
|
||||
{
|
||||
delete _Log;
|
||||
_Log = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs * funcs, PluginCallbacks * calls, PluginInfo * info)
|
||||
{
|
||||
@ -24,23 +52,31 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs * funcs, PluginCallback
|
||||
WSADATA wsaData;
|
||||
#endif // _WIN32
|
||||
_Log = Logger::Get();
|
||||
_Core = Core::Get();
|
||||
_Cmd = CmdManager::Get();
|
||||
// Verify that core components are working
|
||||
if (!_Log)
|
||||
{
|
||||
puts("[SQMOD] Unable to start because the logging class could not be instantiated");
|
||||
return SQMOD_FAILURE;
|
||||
}
|
||||
else if (!_Core)
|
||||
_Core = Core::Get();
|
||||
if (!_Core)
|
||||
{
|
||||
DestroyComponents();
|
||||
puts("[SQMOD] Unable to start because the central core class could not be instantiated");
|
||||
return SQMOD_FAILURE;
|
||||
}
|
||||
_Cmd = CmdManager::Get();
|
||||
if (!_Cmd)
|
||||
{
|
||||
DestroyComponents();
|
||||
puts("[SQMOD] Unable to start because the command class could not be instantiated");
|
||||
return SQMOD_FAILURE;
|
||||
}
|
||||
#if defined(_WIN32)
|
||||
// Initialize the sockets on windows
|
||||
else if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
|
||||
{
|
||||
DestroyComponents();
|
||||
puts("[SQMOD] Unable to start because the windows sockets could not be initialized");
|
||||
return SQMOD_FAILURE;
|
||||
}
|
||||
@ -51,12 +87,13 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs * funcs, PluginCallback
|
||||
_Info = info;
|
||||
|
||||
_Info->uPluginVer = SQMOD_VERSION;
|
||||
strcpy(_Info->szName, SQMOD_NAME);
|
||||
strcpy(_Info->szName, SQMOD_HOST_NAME);
|
||||
|
||||
if (!_Core->Init())
|
||||
{
|
||||
LogFtl("The plugin failed to initialize");
|
||||
_Core->Terminate();
|
||||
DestroyComponents();
|
||||
return SQMOD_FAILURE;
|
||||
}
|
||||
else if (_Clbk)
|
||||
@ -65,15 +102,23 @@ SQMOD_API_EXPORT unsigned int VcmpPluginInit(PluginFuncs * funcs, PluginCallback
|
||||
}
|
||||
else
|
||||
{
|
||||
_Core->Terminate();
|
||||
DestroyComponents();
|
||||
LogFtl("Unable to start because the server callbacks are missing");
|
||||
return SQMOD_FAILURE;
|
||||
}
|
||||
|
||||
// Attempt to initialize the plugin exports
|
||||
InitExports();
|
||||
// Initialization was successful
|
||||
return SQMOD_SUCCESS;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------------------------
|
||||
static int VC_InitServer(void)
|
||||
{
|
||||
if (!_Core)
|
||||
return SQMOD_FAILURE;
|
||||
|
||||
_Core->SetState(1);
|
||||
|
||||
if (_Core->Load())
|
||||
@ -86,18 +131,16 @@ static int VC_InitServer(void)
|
||||
|
||||
static void VC_ShutdownServer(void)
|
||||
{
|
||||
if (!_Core)
|
||||
return;
|
||||
|
||||
_Core->EmitServerShutdown();
|
||||
// Deallocate and release everything obtained at startup
|
||||
_Core->Terminate();
|
||||
// The server still triggers callbacks and we deallocated everything!
|
||||
UnbindCallbacks();
|
||||
// Destroy core components
|
||||
delete _Cmd;
|
||||
delete _Core;
|
||||
delete _Log;
|
||||
_Cmd = NULL;
|
||||
_Core = NULL;
|
||||
_Log = NULL;
|
||||
// Destroy components
|
||||
DestroyComponents();
|
||||
}
|
||||
|
||||
static void VC_Frame(float delta)
|
||||
|
@ -112,6 +112,7 @@
|
||||
#define SQMOD_NAME "Squirrel Module"
|
||||
#define SQMOD_AUTHOR "Sandu Liviu Catalin"
|
||||
#define SQMOD_COPYRIGHT "Copyright (C) 2015 Sandu Liviu Catalin"
|
||||
#define SQMOD_HOST_NAME "SqModHost"
|
||||
#define SQMOD_VERSION 001
|
||||
#define SQMOD_VERSION_STR "0.0.1"
|
||||
#define SQMOD_VERSION_MAJOR 0
|
||||
@ -444,6 +445,8 @@ enum CmdError
|
||||
#define SQMOD_API_EXPORT extern "C" __declspec(dllexport)
|
||||
#elif defined(__GNUC__)
|
||||
#define SQMOD_API_EXPORT extern "C"
|
||||
#else
|
||||
#define SQMOD_API_EXPORT extern "C"
|
||||
#endif
|
||||
|
||||
/* ------------------------------------------------------------------------------------------------
|
||||
|
Reference in New Issue
Block a user