newLISP and IUP UI library oddness

Started by sunmountain, November 12, 2011, 03:49:21 AM

Previous topic - Next topic

sunmountain

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 ?

Lutz

#1
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">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">http://slobin.pp.ru/newlisp/win32demo.lsp

sunmountain

#2
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.

Lutz

#3
QuoteDefines 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' ;)