Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

Creating a plugin without TakeCmd.lib using PureBasic

Aug
1,949
71
Thanks to a person who goes by the handle of yuki on the PureBasic forum,
I now have an alternate method of creating a plugin for TCC using PureBasic.

Ref: External .LIB compiles with ASM Backend, but not C Backend - PureBasic Forums - English
Code:
DeclareModule TakeCmd : EnableExplicit
  
  ; Structures.
  ; ═══════════════════════════════════════════════════════
  
  Structure PluginVersionInfo
    major.l
    minor.l
    build.l
  EndStructure
  
  Structure PluginAuthorInfo
    name.s
    email.s
    url.s
  EndStructure
  
  Structure PluginInfo
    dllName.s
    author.PluginAuthorInfo
    description.s
    functions.s
    version.PluginVersionInfo
    moduleHandle.i
    moduleName.s
  EndStructure
  
  ; Functions: init.
  ; ═══════════════════════════════════════════════════════
  
  ; Loads TakeCmd library functions. Must be called once at
  ; startup before executing other functions.
  Declare InitializeLibrary()
  
  ; Functions: parser.
  ; ═══════════════════════════════════════════════════════
  
  ; Calls the parser to expand and execute the given line.
  Declare.l Command(line.s)
  
  ; Functions: error handling.
  ; ═══════════════════════════════════════════════════════
  
  ; Beeps.
  Declare Honk()
  
EndDeclareModule

Module TakeCmd : EnableExplicit
  
  ; Private types.
  ; ═══════════════════════════════════════════════════════
  Prototype _p_libTakeCmd_Command(line.p-unicode, reserved.i)
  Prototype _p_libTakeCmd_honk()
  
  ; Private state.
  ; ═══════════════════════════════════════════════════════
  Global _g_Command._p_libTakeCmd_Command
  Global _g_honk._p_libTakeCmd_honk
  
  ; Public functions: init.
  ; ═══════════════════════════════════════════════════════
  
  Procedure InitializeLibrary()
    Static isInitialised, libTakeCmd
    If isInitialised
      ; Already initialised OK previously. Skip reattempts.
      ProcedureReturn #True
    ElseIf libTakeCmd
      ; Already failed initialisation previously. Skip reattempts.
      ProcedureReturn #False
    EndIf
    
    libTakeCmd = OpenLibrary(#PB_Any, "TakeCmd.dll")
    If Not libTakeCmd
      ProcedureReturn #False
    EndIf
    
    _g_Command  = GetFunction(libTakeCmd, "Command")
    _g_honk     = GetFunction(libTakeCmd, "honk")
    
    isInitialised = Bool(_g_Command And _g_honk)
    
    ProcedureReturn isInitialised
  EndProcedure
  
  ; Public functions: parser.
  ; ═══════════════════════════════════════════════════════
  
  Procedure.l Command(line.s)
    ProcedureReturn _g_Command(line, #Null)
  EndProcedure
  
  ; Public functions: error handling.
  ; ═══════════════════════════════════════════════════════
  
  Procedure Honk()
    ProcedureReturn _g_honk()
  EndProcedure
  
EndModule

ProcedureDLL InitializePlugin()
  If Not TakeCmd::InitializeLibrary()
    MessageRequester("Error:",
                     "Failed to load <PLUGIN_NAME> plugin!" + #CRLF$ +
                     "Please try and install the latest version from <AUTHOR_URL> or contact support at <AUTHOR_EMAIL>.",
                     #PB_MessageRequester_Error)
    ProcedureReturn 1
  EndIf
  ProcedureReturn 0
EndProcedure

ProcedureDLL GetPluginInfo()
  Static pluginInfo.TakeCmd::PluginInfo
  
  With pluginInfo
    \dllName      = "Example"
    \description  = "Does a thingy."
    \functions    = "thingy"
    \author\name  = "Someone"
    \author\email = "[email protected]"
    \author\url   = "somewhere.com"
    \version\major  = 1
    \version\minor  = 0
    \version\build  = 0
  EndWith
  
  ProcedureReturn @pluginInfo
EndProcedure

ProcedureDLL ShutdownPlugin()
  ProcedureReturn 0
EndProcedure

ProcedureDLL thingy(*argsRaw.Unicode)
  ; Take ping params as input, defaulting to "purebasic.com"
  Protected pingParams.s = Trim(PeekS(*argsRaw, -1, #PB_Unicode))
  If pingParams = ""
    pingParams = "purebasic.com"
  EndIf
  
  TakeCmd::Honk()
  TakeCmd::Command("ping " + pingParams)
  TakeCmd::Honk()
  TakeCmd::Honk()
  
  ProcedureReturn 0
EndProcedure

yuki's code works around the C Compiler bug,
which means that I can now use the C Backend,
or the ASM Backend for compling.

I also no longer require the existence of the TakeCmd.lib file,
as yuki's method only uses the TakeCmd.dll file.

It also allows inline C or assembler code,
if ever the need arises.

Posting here mainly for my future reference,
but others may find the information useful also.

Joe
Ref: Inline x86 ASM
 

Similar threads

Back
Top