Hi there,
I just played around with newLisp and its import capabilites.
My poi there was the famous IUP library, an UI lib, which is C-only.
So here is the code:
(import "iup.dll" "IupOpen")
(import "iup.dll" "IupClose")
(import "iup.dll" "IupText")
(import "iup.dll" "IupButton")
(import "iup.dll" "IupSetAttribute")
(import "iup.dll" "IupGetAttribute")
(import "iup.dll" "IupSetAttributeHandle")
(import "iup.dll" "IupSetAttributes")
(import "iup.dll" "IupSetCallback")
(import "iup.dll" "IupShowXY")
(import "iup.dll" "IupShow")
(import "iup.dll" "IupDialog")
(import "iup.dll" "IupMainLoop")
(import "iup.dll" "IupLabel")
(import "iup.dll" "IupVbox")
(define (quit_cb) (- 0 3)) ; IUP_DEFAULT=-3
(IupOpen)
(set 'quit_bt (IupButton "Quit" 0))
(IupSetCallback quit_bt "ACTION" (callback 0 'quit_cb))
(set 'label (IupLabel "Very long label"))
(IupSetAttribute label "EXPAND=YES")
(IupSetAttribute label "ALIGNMENT=ACENTER")
(set 'vbox (IupVbox label quit_bt 0))
(IupSetAttribute vbox "MARGIN" "10x10")
(IupSetAttribute vbox "GAP" "5")
(IupSetAttribute vbox "ALIGNMENT=ACENTER")
(set 'dialog (IupDialog vbox) )
(IupSetAttribute dialog "EXPAND" "YES")
(IupSetAttribute dialog "SIZE" "QUARTER")
(IupSetAttributeHandle dialog "DEFAULTESC" quit_bt)
(IupShow dialog)
(IupSetAttribute dialog "TITLE" "YES")
(IupMainLoop)
(IupClose)
(exit)
What is driving me nuts is this: if I call
(IupSetAttribute dialog "TITLE" "YES")
after (IupShow dialog), the title is displayed.
If I do it the other way around, it does not. Sometimes a single char is displayed like F or so.
I just coded this in Python using ctypes, and there the order of the operations does not matter.
The title is always displayed.
Even in an hand-coded C equivalent the order does not matter.
OS is Windows 7 Ultimate, 32 Bit, newLisp is newLISP v.10.3.5 on Win32 IPv4/6 UTF-8 and
the IUP dll offers this version:
(import "iup.dll" "IupVersion")
(get-string (IupVersion))
"3.5"
Any hints ?
I am not familiar with iup.dll, but here are some pointers to what usually are the problems when importing functions:
- make sure to use the correct calling convention for this DLL. By default Windows uses stdcall, but perhaps you have to specify "cdecl"
- probably one of the parameters in one of the imported functions is not passed correctly. E.g. Windows often uses pointers to pass string buffers or even numbers. If addresses are passed, for Windows to deposit a result there, memory for these addresses has to be reserved using (dup " 00" N). Where N is frequently 4 for a 32-bit long number or pointer or the maximum length of a string buffer plus the terminating zero.
There is a longer chapter about importing issues in newLISP here:
http://www.newlisp.org/CodePatterns.html#toc-23
an interesting application doing Windows low-level stuff and using a 'callback' function here:
http://slobin.pp.ru/newlisp/win32demo.lsp
I think I can imagine what goes on.
I just did this:
(IupStoreAttribute dialog "TITLE" (date))
and now it works reliably.
I guess that if I pass a temporary string, it's thrown away after the last reference is away.
This is right after the ")".
So the reference is gone.
Why this works after IupShow is called - I don't know.
The IUP manual says:
Quote
IupStoreAttribute
Defines an attribute for an interface element but the string is internally duplicated.
So I used this function - and it works as expected.
I guess that my Python and C code works has todo with a) garbage collector in python b) the visibility and
storage for constant strings in C.
Quote
Defines an attribute for an interface element but the string is internally duplicated.
That's why it works, because it is duplicated.
If "Title" is part of the program text it will never be waste recycled(*), but when the statement is entered interactively from the command-line then yes.
To preserve your attributes, constants etc. you could do:
(constant 'TITLE "TITLE")
(constant 'FOO 123)
...
They are now protected against accidental assignment, redefinition etc..
(*) as opposed to 'garbage collected' ;)