Passing a structure to a macro?

Just starting out? Need help? Post your questions and find answers here.
devox
User
User
Posts: 32
Joined: Thu Apr 01, 2021 7:25 pm

Passing a structure to a macro?

Post by devox »

Hi,

So I can do this basic macro like this and it works.

Code: Select all

Structure Plugin
  Name$
  Description$
EndStructure

Macro CreatePlugin(PluginStruct)
  Global Name$ = PluginStruct\Name$  
EndMacro

Define MyPlugin.Plugin
MyPlugin\Name$ = "RandomName"
CreatePlugin(MyPlugin)

Debug Name$
If I do my macro like this it doesn't work and says "The following variable doesn't have a 'Structure'?

Code: Select all

Structure Plugin
  Name$
  Description$
EndStructure

Macro CreatePlugin(PluginStruct)
  Global *Name
  ProcedureDLL AttachProcess(Instance)
    *Name = Ascii(PluginStruct\Name$)
  EndProcedure
EndMacro

Define MyPlugin.Plugin
MyPlugin\Name$ = "RandomName"
CreatePlugin(MyPlugin)

Debug *Name
Many thanks
User avatar
NicTheQuick
Addict
Addict
Posts: 1224
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

Re: Passing a structure to a macro?

Post by NicTheQuick »

That's because after the Macro was evaluated it looks like this:

Code: Select all

Define MyPlugin.Plugin
MyPlugin\Name$ = "RandomName"
  Global *Name
  ProcedureDLL AttachProcess(Instance)
    *Name = Ascii(MyPlugin\Name$)
  EndProcedure
And then you can see that `MyPlugin` is not in the global scope but only in the main scope. Either you have to write `Global MyPlugin.Plugin` or you have to use the `Shared` keyword within the `ProcedureDLL`.
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.
User avatar
Lunasole
Addict
Addict
Posts: 1091
Joined: Mon Oct 26, 2015 2:55 am
Location: UA
Contact:

Re: Passing a structure to a macro?

Post by Lunasole »

Or try passing something like this, passing structure pointer (or just a pointer).

Code: Select all

Structure Plugin
  Name$
  Description$
EndStructure

Macro CreatePlugin(PluginStruct)
  Global *Name
  ProcedureDLL AttachProcess(Instance, PluginStruct.Plugin)
    *Name = Ascii(PluginStruct\Name$)
  EndProcedure
EndMacro

Define *MyPlugin.Plugin = AllocateStructure(Plugin)
*MyPlugin\Name$ = "RandomName"
CreatePlugin(*MyPlugin)

Debug *Name

FreeStructure(*MyPlugin)
Anyway I'm not sure if I got it right, your code looks a bit crazy :) At least without full picture of now it's used.
"W̷i̷s̷h̷i̷n̷g o̷n a s̷t̷a̷r"
devox
User
User
Posts: 32
Joined: Thu Apr 01, 2021 7:25 pm

Re: Passing a structure to a macro?

Post by devox »

Thanks @NicTheQuick that has sorted it, I see now!

@Lunasole
Anyway I'm not sure if I got it right, your code looks a bit crazy :) At least without full picture of now it's used.
Currently this is just experimenting and prototyping, but the idea is I want a macro that I can pass a structure of settings that define the properties of a plugin which is simple a DLL that exports a variable number of functions and variables depending on the structure fields. It needs to be a macro as it needs to be compile time due to the exports of the DLL.
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Passing a structure to a macro?

Post by #NULL »

If you use EnableExplicit in the beginning of your code (and declare all your variables), you will get a better error that makes it easier to see that you have created an undeclared local variable within the procedure.
devox
User
User
Posts: 32
Joined: Thu Apr 01, 2021 7:25 pm

Re: Passing a structure to a macro?

Post by devox »

Thanks @#NULL I will try to use the from now on!

On variables what is the difference between define and protected?
User avatar
Tenaja
Addict
Addict
Posts: 1948
Joined: Tue Nov 09, 2010 10:15 pm

Re: Passing a structure to a macro?

Post by Tenaja »

devox wrote:Thanks @#NULL I will try to use the from now on!

On variables what is the difference between define and protected?
A Protected variable is one that is "local" and can only be referenced within the procedure it is declared. You can, for instance, name a protected variable the same as a global variable is named, with it being a separate variable without conflict or relation.

Define let's you define multiple variables at once, and their scope matches the definition location. They are not, by default, accessible within a procedure. (Remember, pb has "free form" code that is not in any procedures, unlike C.)

Global let's you declare the variable as usable everywhere.
User avatar
skywalk
Addict
Addict
Posts: 3972
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Passing a structure to a macro?

Post by skywalk »

I use this approach, but no Macro() when setting the string fields of a structure.
Maybe someone else has a safe way for that?

Code: Select all

EnableExplicit
Structure SomeStruct
  u.u
  l.l
  i.i
  d.d
  s$      ; Named Field
  s2$     ; Named Field2
EndStructure
;-{ MACROS
Macro SomeStruct_SetU(pSomeStruct, ParmOffs, Uval)
  ; Receives ptr to SomeStruct structure.
  PokeU(pSomeStruct + ParmOffs, Uval)
EndMacro
Macro SomeStruct_SetL(pSomeStruct, ParmOffs, Lval)
  ; Receives ptr to SomeStruct structure.
  PokeL(pSomeStruct + ParmOffs, Lval)
EndMacro
Macro SomeStruct_SetI(pSomeStruct, ParmOffs, Ival)
  ; Receives ptr to SomeStruct structure.
  PokeI(pSomeStruct + ParmOffs, Ival)
EndMacro
Macro SomeStruct_SetD(pSomeStruct, ParmOffs, Dval)
  ; Receives ptr to SomeStruct structure.
  PokeD(pSomeStruct + ParmOffs, Dval)
EndMacro
Macro SomeStruct_GetL(pSomeStruct, ParmOffs)
  ; Receives ptr to SomeStruct structure.
  PeekL(pSomeStruct + ParmOffs)
EndMacro
Macro SomeStruct_GetI(pSomeStruct, ParmOffs)
  ; Receives ptr to SomeStruct structure.
  PeekI(pSomeStruct + ParmOffs)
EndMacro
Macro SomeStruct_GetD(pSomeStruct, ParmOffs)
  ; Receives ptr to SomeStruct structure.
  PeekD(pSomeStruct + ParmOffs)
EndMacro
Macro SomeStruct_Get_Str(pSomeStruct, ParmOffs)
  ; Receives ptr to SomeStruct structure.
  ; Initialize Structure is required to avoid NULL pointer.
  PeekS(PeekI(pSomeStruct + ParmOffs))
EndMacro
Procedure SomeStruct_Set_Str(*p.SomeStruct, ParmOffs$, ParmVal$)
  ; Not using Macro() to avoid string memory management.
  Select ParmOffs$
  Case "s$"
    *p\s$ = ParmVal$
  Case "s2$"
    *p\s2$ = ParmVal$
  EndSelect
EndProcedure
;-} MACROS
Define p.SomeStruct
Define.s s$ = "s$"
SomeStruct_SetD(p, OffsetOf(SomeStruct\d), #PI)
Debug p\d
SomeStruct_Set_Str(p, "s$", "Hello")
Debug p\s$
p\s2$ = "1234567890"
p\s$ = SomeStruct_Get_Str(p, OffsetOf(SomeStruct\s2$))
Debug p\s$
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Post Reply