Archive: Plugin / ExDLL question


Plugin / ExDLL question
Am making a plugin and in looking at ExDLL I see the exdll definition:

#define EXDLL_INIT() { \
g_stringsize=string_size; \
g_stacktop=stacktop; \
g_variables=variables; }

The function def in exdll.c looks like:
void __declspec(dllexport) myFunction(HWND hwndParent,
int string_size,
char *variables,
stack_t **stacktop,
extra_parameters *extra)

What are the "extra_parameters" and can they be used?
I.e. how would they get set in the plugin function call?

Clarification would be Appreciated!


In exdll.h:


typedef struct {
int autoclose;
int all_user_var;
int exec_error;
int abort;
int exec_reboot;
int reboot_called;
int XXX_cur_insttype; // deprecated
int XXX_insttype_changed; // deprecated
int silent;
int instdir_error;
int rtl;
int errlvl;
} exec_flags;

typedef struct {
exec_flags *exec_flags;
int (__stdcall *ExecuteCodeSegment)(int, HWND);
} extra_parameters;

I guess some behave of the installer is passed though this param? :weird:

DOH!, thx Joelito.

Hmmm dont see it or the ExecuteCodeSegment function defined in there ever being referenced. Must be for "future enhancements" or something.

Follow up question: how do most people handle variable number of parms to a plugin, include the number of parms as the last parm on the call statement itself?

I.E. DllName::FunctionName "parm1" "parm2" ... "parmN" "N"
or something.

I am thinking "bad" things happens if you pop more parms that were pushed in the call??


how do most people handle variable number of parms to a plugin, include the number of parms as the last parm on the call statement itself?
I don't know everyone else but I use popstring from exdll.h, as many times I need a param to be passed.

The popstring function included with the ExDLL framework just returns 1 when no more data is located on the stack. So just keep popping until you get 1 in return from popstring.


Thx saivert and Joelito!:up:

And to think... I actually DID study exdll.h pretty thououghly yesterday! :o Getting OLD I guess.


I guess if you take a look on the source code for exehead subproject of the source code for NSIS, you may get a hint about what the heck "ExecuteCodeSegment" is all about.

My personal guess is that you can execute parts of the script from a plugin. Maybe execute a function?? It would be great if this was a possibility cos' then a plugin can call a script function directly instead of the usual routine of letting the control fall back to NSIS' main UI thread as InstallOptions does. And hooking special messages is also pretty ugly.


Hmmm, my guess would be that its used as part of the actual NSIS event hadler itself, i.e. seems like its responding to various SendMessage(s) to handle callbacks, aborts, which page to show processing?, progress updates, etc.

A bit beyond me at this point! I would need substantial "developer docs" and lotsa time with the debugger to wend my way thru this!


Popping until the stack is empty is not a good idea. The stack might contain other things but parameters to your plug-in. Simply require the user to put an end marker such as "--" and pop until you find it.

ExecuteCodeSegment executes NSIS code segement. You can use it to execute code pointers the user may pass as a parameter. For example, the user can use GetFunctionAddress to pass a function pointer. See my recently posted nsXML plug-in for an example.


Thx kichik, I was thinking the same.

This *might* be a nice future feature: i.e. have an optional switch for plugins call statement /markstack and compiler would automatically push a "stack marker" before pushing the parms. I realize I can just do that as you suggested but having a formal, well defined, stack marker, you could then recommend that it be used. You could even make it the default and add switch /nostackmarker to prevent the stack marker (possibly with a Setxxx attribute to define default behaviour for backwards compatability).
Just a thought.


NSIS plugin guide.
Yup yup! Nice idea. But I think the problem is more related to how people generally code their NSIS plugins. They use more stack items instead of using just the first string for all parameters.

I like using just the first item and then pack all parameters options data in this one. Just like when you are passing parameters to a Win32 program, the program only gets one string to work with and has to parse this.
With NSIS plugins we get a lot of strings (stack items) we must parse and that usually complicates things.

Why not got for a "-o1 -o2 --option3" syntax instead of pushing hundreds of strings on the stack. The default size limit on strings in NSIS is 1024, and should be more than enough for most things. If neccessary you could pass a switch in the first string that tells the plugin to pop one more string in order to get more information.

Why can't someone in the NSIS dev team write a programmers guide or something, so people can write code that conforms to some guidelines.

EDIT: What bout my post??


Originally posted by Arrby
Thx kichik, I was thinking the same.

This *might* be a nice future feature: i.e. have an optional switch for plugins call statement /markstack and compiler would automatically push a "stack marker" before pushing the parms. I realize I can just do that as you suggested but having a formal, well defined, stack marker, you could then recommend that it be used. You could even make it the default and add switch /nostackmarker to prevent the stack marker (possibly with a Setxxx attribute to define default behaviour for backwards compatability).
Just a thought.
Good idea. /END would be most suitable because a few plugins use that already (so they won't have to be recompiled)

-Stu