Author Topic: IDLL  (Read 18615 times)

JRS

  • Guest
IDLL
« on: December 12, 2010, 11:50:14 pm »
I added a couple more wrapper functions to the gtk-server.so extension module. These two functions prefix what the user passes for IUSE and IDECLARE. ("gtk_server_require " and "gtk_server_define ") internally. I added them to make the .sbh files more readable and getting use to making changes to the gtk-server library.

Depending on your style of coding, the IUSE and IDECLARE can be anywhere in your program. (as long as you only call it once and before use)




Code: Text
  1. ' INTERFACE
  2. DECLARE SUB IDLL ALIAS "_gtk" LIB "gtk-server"
  3. DECLARE SUB IUSE ALIAS "_gtk_require" LIB "gtk-server"
  4. DECLARE SUB IDECLARE ALIAS "_gtk_define" LIB "gtk-server"
  5. DECLARE SUB VARPTR ALIAS "varptr" LIB "gtk-server"
  6.  
  7. ' GDA4
  8. IUSE("libgda-4.0.so")
  9. IUSE("libgda-ui-4.0.so")
  10.  
  11. ' DECLARE
  12.  
  13. IDECLARE("gtk_init NONE NONE 2 NULL NULL")
  14. IDECLARE("gtk_dialog_new_with_buttons NONE WIDGET 8 STRING WIDGET INT STRING INT STRING INT NULL")
  15. IDECLARE("gdaui_login_new NONE WIDGET 1 STRING")
  16. IDECLARE("gtk_box_pack_start NONE NONE 5 WIDGET WIDGET BOOL BOOL INT")
  17. IDECLARE("gtk_dialog_get_content_area NONE WIDGET 1 WIDGET")
  18. IDECLARE("gtk_widget_show NONE NONE 1 WIDGET")
  19. IDECLARE("gtk_dialog_run delete-event INT 1 WIDGET")
  20. IDECLARE("gdaui_login_get_connection_information NONE WIDGET 1 WIDGET")
  21. IDECLARE("gda_connection_open_from_string NONE WIDGET 5 STRING STRING POINTER INT NULL")
  22. IDECLARE("gtk_widget_destroy NONE NONE 1 WIDGET")
  23. IDECLARE("gda_execute_select_command NONE WIDGET 3 WIDGET STRING NULL")
  24. IDECLARE("g_object_unref NONE NONE 1 WIDGET")
  25. IDECLARE("gtk_window_new delete-event WIDGET 1 INT")
  26. IDECLARE("gdaui_grid_new NONE WIDGET 1 WIDGET")
  27. IDECLARE("gtk_container_add NONE NONE 2 WIDGET WIDGET")
  28. IDECLARE("gtk_widget_show_all NONE NONE 1 WIDGET")
  29. IDECLARE("gtk_server_callback NONE STRING 1 STRING")
  30. IDECLARE("gtk_window_set_default_size NONE NONE 3 WIDGET INT INT")
  31. IDECLARE("gtk_window_set_title NONE NONE 2 WIDGET STRING")
  32. IDECLARE("strncpy NONE STRING 3 POINTER POINTER INT")
  33. IDECLARE("strdup NONE STRING 1 POINTER")
  34.  
  35.  
  36. CONST GTK_STOCK_CANCEL = "gtk-cancel"
  37. CONST GTK_STOCK_OK = "gtk-ok"
  38. CONST GTK_RESPONSE_NONE = -1
  39. CONST GTK_RESPONSE_OK = -5
  40. CONST GDA_CONNECTION_OPTIONS_NONE = 0
  41. CONST GTK_WINDOW_TOPLEVEL = 0
  42. CONST GTK_DIALOG_MODAL = 1
  43. CONST provider = 4
  44. CONST cnc_string = 12
  45.  
  46.  
  47. FUNCTION STRPTR(pointer)
  48. LOCAL info_str
  49.  
  50. info_str = 0
  51. IDLL("strncpy " & VARPTR(info_str) & " " & pointer & " 4")
  52. STRPTR = IDLL("strdup " & info_str)
  53.  
  54. END FUNCTION
  55.  
  56.  
  57. SUB gtk_main
  58. LOCAL event
  59.  
  60. REPEAT
  61.   event = IDLL("gtk_server_callback wait")
  62. UNTIL event = window
  63.  
  64. END SUB
  65.  

The GNOME-DB-GRID code challenge main program.

Code: Text
  1. ' GNOME-DB GRID
  2.  
  3. INCLUDE "gnome-db.sbh"
  4.  
  5. IDLL("gtk_init 0 0")
  6. IDLL("gdaui_init")
  7.  
  8. ' DB Control Window
  9. window = IDLL("gtk_dialog_new_with_buttons \"Select the Data Source to connect to\" 0 " & GTK_DIALOG_MODAL & " " & GTK_STOCK_CANCEL & " " & GTK_RESPONSE_NONE & " " & GTK_STOCK_OK & " " & GTK_RESPONSE_OK & " 0")
  10. login = IDLL("gdaui_login_new NULL")
  11. IDLL("gtk_box_pack_start " & IDLL("gtk_dialog_get_content_area " & window) & " " &  login & " TRUE TRUE 0")
  12. IDLL("gtk_widget_show " & login)
  13. IF IDLL("gtk_dialog_run " & window) <> GTK_RESPONSE_OK THEN
  14.   PRINT "Cancelled!\n"
  15.   END
  16. END IF
  17. dsninfo = IDLL("gdaui_login_get_connection_information " & login)
  18. cnc = IDLL("gda_connection_open_from_string " & STRPTR(dsninfo + provider) & " " & STRPTR(dsninfo + cnc_string) & " " & " 0 0 0")
  19. data_model = IDLL("gda_execute_select_command " & cnc & " \"SELECT * FROM customers\" 0")
  20. IDLL("gtk_widget_destroy " & window)
  21.  
  22. ' DB Data Grid
  23. window = IDLL("gtk_window_new 0")
  24. IDLL("gtk_window_set_title " & window & " \"GNOME-DB Grid Control Example\"")
  25. IDLL("gtk_window_set_default_size " & window & " 400 200")
  26. grid = IDLL("gdaui_grid_new " & data_model)
  27. IDLL("g_object_unref " & data_model)
  28. IDLL("gtk_container_add " & window & " " & grid)
  29. IDLL("gtk_widget_show_all " & window)
  30.  
  31. gtk_main()
  32.  
  33. IDLL("g_object_unref " & cnc)
  34.  

GNOME-DB-GRID sample.c
GNOME-DB GdaBrowser

Current ScriptBasic version of the gtk-server.c code modified for this demo. I would think these changes would work with the Windows and Mac versions of GTK-Server. (SB version)

Code: [Select]
#ifdef GTK_SERVER_SCRIPTBASIC
besVERSION_NEGOTIATE
    return (int)INTERFACE_VERSION;
besEND

besSUB_START

besEND

besSUB_FINISH

besEND

besFUNCTION(_gtk)
    VARIABLE ptr;
    char* arg0;
    char* retstr;

    if(besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
    if(besARGNR<1) return EX_ERROR_TOO_FEW_ARGUMENTS;

    ptr = besARGUMENT(1);
    besDEREFERENCE(ptr);
    arg0 = besCONVERT2ZCHAR(besCONVERT2STRING(ptr),arg0);

    retstr = (char*)gtk(arg0);

    besALLOC_RETURN_STRING(strlen(retstr));
    memcpy(STRINGVALUE(besRETURNVALUE),retstr,strlen(retstr));

    besFREE(arg0);
besEND


besFUNCTION(_gtk_require)
    VARIABLE ptr;
    char* arg0;
    char* retstr;

    if(besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
    if(besARGNR<1) return EX_ERROR_TOO_FEW_ARGUMENTS;

    ptr = besARGUMENT(1);
    besDEREFERENCE(ptr);

    #define GTKSRV_REQUIRE "gtk_server_require "

    arg0 = besCONVERT2ZCHAR(besCONVERT2STRING(strcat(GTKSRV_REQUIRE,STRINGVALUE(ptr))),arg0);

    retstr = (char*)gtk(arg0);

    besALLOC_RETURN_STRING(strlen(retstr));
    memcpy(STRINGVALUE(besRETURNVALUE),retstr,strlen(retstr));

    besFREE(arg0);
besEND

 
besFUNCTION(_gtk_define)
    VARIABLE ptr;
    char* arg0;
    char* retstr;

    if(besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
    if(besARGNR<1) return EX_ERROR_TOO_FEW_ARGUMENTS;

    ptr = besARGUMENT(1);
    besDEREFERENCE(ptr);

    #define GTKSRV_DEFINE "gtk_server_define "

    arg0 = besCONVERT2ZCHAR(besCONVERT2STRING(strcat(GTKSRV_DEFINE,STRINGVALUE(ptr))),arg0);

    retstr = (char*)gtk(arg0);

    besALLOC_RETURN_STRING(strlen(retstr));
    memcpy(STRINGVALUE(besRETURNVALUE),retstr,strlen(retstr));

    besFREE(arg0);
besEND


besFUNCTION(varptr)
  VARIABLE ptr;

  if(besARGNR>1) return EX_ERROR_TOO_MANY_ARGUMENTS;
  if(besARGNR<1) return EX_ERROR_TOO_FEW_ARGUMENTS;

  besALLOC_RETURN_LONG
  
  ptr = besARGUMENT(1);
  besDEREFERENCE(ptr);
  
  LONGVALUE(besRETURNVALUE) = (int)ptr;

besEND


/* Needed to compile standalone Scriptbasic programs */
SLFST VISIO_SLFST[] = {

    {"versmodu", versmodu},
    {"bootmodu", bootmodu},
    {"finimodu", finimodu},
    {"_gtk", _gtk},
    {"_gtk_require",_gtk_require},
    {"_gtk_define",_gtk_define},
    {"varptr",varptr},
    {NULL, NULL}
};

#endif /* End of ScriptBasic code */
« Last Edit: December 13, 2010, 02:34:26 am by JRS »

JRS

  • Guest
Re: IDLL
« Reply #1 on: December 13, 2010, 03:49:27 am »
If you prefer more of a traditional function calling method rather then using a single string, I added a DLL (function CALL interface to IDLL) just for you.  :)

Code: [Select]
' INTERFACE
DECLARE SUB IDLL ALIAS "_gtk" LIB "gtk-server"
DECLARE SUB IUSE ALIAS "_gtk_require" LIB "gtk-server"
DECLARE SUB IDECLARE ALIAS "_gtk_define" LIB "gtk-server"
DECLARE SUB VARPTR ALIAS "varptr" LIB "gtk-server"

' GDA4
IUSE("libgda-4.0.so")
IUSE("libgda-ui-4.0.so")

' DECLARE

IDECLARE("gtk_init NONE NONE 2 NULL NULL")
IDECLARE("gtk_dialog_new_with_buttons NONE WIDGET 8 STRING WIDGET INT STRING INT STRING INT NULL")
IDECLARE("gdaui_login_new NONE WIDGET 1 STRING")
IDECLARE("gtk_box_pack_start NONE NONE 5 WIDGET WIDGET BOOL BOOL INT")
IDECLARE("gtk_dialog_get_content_area NONE WIDGET 1 WIDGET")
IDECLARE("gtk_widget_show NONE NONE 1 WIDGET")
IDECLARE("gtk_dialog_run delete-event INT 1 WIDGET")
IDECLARE("gdaui_login_get_connection_information NONE WIDGET 1 WIDGET")
IDECLARE("gda_connection_open_from_string NONE WIDGET 5 STRING STRING POINTER INT NULL")
IDECLARE("gtk_widget_destroy NONE NONE 1 WIDGET")
IDECLARE("gda_execute_select_command NONE WIDGET 3 WIDGET STRING NULL")
IDECLARE("g_object_unref NONE NONE 1 WIDGET")
IDECLARE("gtk_window_new delete-event WIDGET 1 INT")
IDECLARE("gdaui_grid_new NONE WIDGET 1 WIDGET")
IDECLARE("gtk_container_add NONE NONE 2 WIDGET WIDGET")
IDECLARE("gtk_widget_show_all NONE NONE 1 WIDGET")
IDECLARE("gtk_server_callback NONE STRING 1 STRING")
IDECLARE("gtk_window_set_default_size NONE NONE 3 WIDGET INT INT")
IDECLARE("gtk_window_set_title NONE NONE 2 WIDGET STRING")
IDECLARE("strncpy NONE STRING 3 POINTER POINTER INT")
IDECLARE("strdup NONE STRING 1 POINTER")


CONST GTK_STOCK_CANCEL = "gtk-cancel"
CONST GTK_STOCK_OK = "gtk-ok"
CONST GTK_RESPONSE_NONE = -1
CONST GTK_RESPONSE_OK = -5
CONST GDA_CONNECTION_OPTIONS_NONE = 0
CONST GTK_WINDOW_TOPLEVEL = 0
CONST GTK_DIALOG_MODAL = 1
CONST provider = 4
CONST cnc_string = 12


FUNCTION DLL(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
LOCAL arg_str
  arg_str = STR(a0) & " " & STR(a1) & " " & STR(a2) & " " & STR(a3) & " " & STR(a4) & " " & STR(a5) & " " & STR(a6) & " " & STR(a7) & " " & STR(a8) & " " & STR(a9)
  DLL = IDLL(arg_str)
END FUNCTION


FUNCTION STRPTR(pointer)
LOCAL info_str

info_str = 0
IDLL("strncpy " & VARPTR(info_str) & " " & pointer & " 4")
STRPTR = IDLL("strdup " & info_str)

END FUNCTION


SUB gtk_main
LOCAL event

REPEAT
  event = IDLL("gtk_server_callback wait")
UNTIL event = window

END SUB

Nothing else was changed in the gnome-db.sbh include file. Notice the difference between this version of gda.sb using DLL and the previous version using IDLL.

Code: Text
  1. ' GNOME-DB GRID
  2.  
  3. INCLUDE "gnome-db.sbh"
  4.  
  5. DLL("gtk_init", 0, 0)
  6. DLL("gdaui_init")
  7.  
  8. ' DB Control Window
  9. window = DLL("gtk_dialog_new_with_buttons","Select the Data Source to connect to", 0, GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_NONE, GTK_STOCK_OK, GTK_RESPONSE_OK, 0)
  10. login = DLL("gdaui_login_new", NULL)
  11. DLL("gtk_box_pack_start", DLL("gtk_dialog_get_content_area", window), login, TRUE, TRUE, 0)
  12. DLL("gtk_widget_show", login)
  13. IF DLL("gtk_dialog_run", window) <> GTK_RESPONSE_OK THEN
  14.   PRINT "Cancelled!\n"
  15.   END
  16. END IF
  17. dsninfo = DLL("gdaui_login_get_connection_information", login)
  18. cnc = DLL("gda_connection_open_from_string", STRPTR(dsninfo + provider), STRPTR(dsninfo + cnc_string), 0, 0, 0)
  19. data_model = DLL("gda_execute_select_command", cnc, "SELECT * FROM customers", 0)
  20. DLL(gtk_widget_destroy, window)
  21.  
  22. ' DB Data Grid
  23. window = DLL("gtk_window_new", 0)
  24. DLL("gtk_window_set_title", window, "GNOME-DB Grid Control Example")
  25. DLL("gtk_window_set_default_size", window, 400, 200)
  26. grid = DLL("gdaui_grid_new", data_model)
  27. DLL("g_object_unref", data_model)
  28. DLL("gtk_container_add", window, grid)
  29. DLL("gtk_widget_show_all", window)
  30.  
  31. gtk_main()
  32.  
  33. DLL("g_object_unref", cnc)
  34.  
« Last Edit: December 13, 2010, 04:05:07 am by JRS »

AIR

  • Guest
Re: IDLL
« Reply #2 on: December 13, 2010, 11:30:57 am »
Quote
IDECLARE("strdup NONE STRING 1 POINTER")

strdup calls malloc() to create the copy of the string.

Wouldn't that potentially cause an issue on long running programs, because the copy is never "free()" 'd?

JRS

  • Guest
Re: IDLL
« Reply #3 on: December 13, 2010, 01:22:13 pm »
My understanding of how SB manages memory is that it releases all memory used after scriba ends. Keep in mind that I'm calling strdup() via GTK-Server which is a SB extension module following the SB memory allocation guidelines established.

Maybe Peter Verhas can address this in a better way.


AIR

  • Guest
Re: IDLL
« Reply #4 on: December 13, 2010, 02:01:33 pm »
Yes, but normally sb handles the memory allocation.  Perhaps gtk-server does as well, but I don't know.  However, calling strdup falls outside of that.  It's like calling malloc/calloc directly within a module.

For short demo programs this is not really an issue.  For long running apps it could be an issue at some point.

Is it possible to run valgrind against a running sb script (actually against scriba)?  If you have leaks, that's one way to discover where they're coming from....

jcfuller

  • Guest
Re: IDLL
« Reply #5 on: December 13, 2010, 02:19:58 pm »

Is it possible to run valgrind against a running sb script (actually against scriba)?  If you have leaks, that's one way to discover where they're coming from....

The Tests I did  with valgrind using bacon and gtk always showed a memory leak. My understanding is you cannot get an accurate result because of the way gtk handles memory???

James

verhas

  • Guest
Re: IDLL
« Reply #6 on: December 13, 2010, 02:36:49 pm »
If you call strdup and you do not free the memory yourself ScriptBasic will have no means to free the memory.

ScriptBasic allocates memory for the interpreter via its own memory management modules that themselves use malloc/free. If you go round bypassing these functions ScriptBasic will not know anything about those memory allocations and will not free the memory when the interpreter exists.

Of course memory is freed by the OS when the process exits, but I believe that is a bit late.

Sorry folks. I am a programmer and not a magician. ScriptBasic is complex but not magic.

JRS

  • Guest
Re: IDLL
« Reply #7 on: December 13, 2010, 02:52:24 pm »
I may be within the SB rules here.

My STRPTR() function in scriba calls GTK-Server to perform the operation. I am grabbing a pointer from the dsninfo structure that points to a null terminated string. I then copy this pointer to the SB long. (redirecting the pointer to it's initial 0 data to a string pointer in dsninfo) Finally I use the same variable that was a long, changed it to a string (SB typeless magic) with a pointer reference change and return the results of the duplication to itself. (no animals or variables were abused in this procedure)

I know it's on the fringe of legal but I think I'm okay with the results. Is there any way to prove I'm doing bad things when I see no side effects from it's use?

When I was using strncpy for copying the pointer and the data (assigning a length) to the initial defined SB variable, I would get seg faults or GTK-Server dumping a backtrace to the console. Using strdup to move the contents of the string, I didn't need to know the length and strdup handled the operation internally.

Thinking about this a bit more after the joy of getting it working has subsided, there may be a memory leak were I dissociated the pointer to the initial zero value being stored by pointing it to the string reference in dsninfo. I could free the original long data before leaving my STRPTR function.
« Last Edit: December 13, 2010, 04:25:49 pm by JRS »

JRS

  • Guest
Re: IDLL
« Reply #8 on: December 13, 2010, 04:40:42 pm »
I took my own advice (and your suggestions) and changed the STRPTR function to free the memory used to store the initial long (zero) data.

Code: [Select]
DLL("gtk_server_define free NONE NONE 1 POINTER")
...

FUNCTION STRPTR(pointer)
LOCAL info_str, info_ptr

info_str = 0
info_ptr = VARPTR(info_str)
DLL("strncpy " & VARPTR(info_str) & " " & pointer & " 4")
STRPTR = DLL("strdup " & info_str)
DLL("free " & info_ptr)

END FUNCTION

I didn't get any complaints from SB or GTK-Server with this latest change. (nor did I before the change)

Thanks guys for the concern and advice with cleaning up the raw activity going on under the covers.
« Last Edit: December 13, 2010, 04:52:55 pm by JRS »

AIR

  • Guest
Re: IDLL
« Reply #9 on: December 13, 2010, 05:49:47 pm »
Quote
STRPTR = DLL("strdup " & info_str)
DLL("free " & info_ptr)

I think when you hit the STRPR = line, your function is done so the DLL() call never happens.

Let me illustrate in C what I mean:
Code: [Select]
#include <stdio.h>

int myfunc() {
  printf("Inside Function\n");
  return 1;
  printf("Never Printed\n");
  return 0;
}

int main() {
  printf("Return Value = %i\n",myfunc());
}

Quote from: Output
[riveraa@Armando-Riveras-MacBook-Pro ~] $ gcc ret.c -o ret
[riveraa@Armando-Riveras-MacBook-Pro ~] $ ./ret
Inside Function
Return Value = 1
[riveraa@Armando-Riveras-MacBook-Pro ~] $

The point I was making regarding strdup() is that the space allocation is taking place outside of sb or gtk-server's alloc/dealloc routines because strdup() is calling malloc() directly.  So it doesn't matter if you follow sb's recommended practices, the space allocation is on it's own "island".  Neither sb or gtk-server own it, so it's up to the caller to free the space.  In this case, STRPTR.

A.

JRS

  • Guest
Re: IDLL
« Reply #10 on: December 13, 2010, 06:11:46 pm »
strdup is copying the string data up to the NULL to a pointer the user passes to its allocated buffer. GTK-Server is defining this buffer as the return string to ScriptBasic. (not my responsibility to free Peter's allocations) The only slippery thing I'm guilty of is using a SB defined LONG to fool strdup to think the address I'm passing is the pointer to the string defined in dsninfo when in fact it's a ghost structure element I have control over. The poor zero value that was being pointed to is now dissociated with SB & GTK-Server so the new free call I added takes care of that problem. Everything else is managed by a Peter.

Quote from: AIR
I think when you hit the STRPR = line, your function is done so the DLL() call never happens.

All I'm doing at the script level is building a command string for GTK-Server to process. Before the Gtk function gets passed to GTK-Server for processing, I have a couple command string building calls to make first. (STRPTR) Remember SB is an interpreter and the functions are being called at runtime via a DynaCall like interface to the API. (same as the DYC extension module under SB Windows)

« Last Edit: December 13, 2010, 06:27:46 pm by JRS »

AIR

  • Guest
Re: IDLL
« Reply #11 on: December 13, 2010, 06:31:55 pm »
Right.  A POINTER.  A pointer to what? A memory location.  With no space allocated.

When you call strdup(), it's not returning a string, but a POINTER to a string buffer.  THAT'S what your passed pointer is now pointing to.

So, who owns that buffer?  YOU.  That's the point.

Quote from: MAN strdup
DESCRIPTION
     The strdup() function allocates sufficient memory for a copy of the
     string s1, does the copy, and returns a pointer to it.  The pointer may
     subsequently be used as an argument to the function free(3).

So you see, you have what amounts to a leak because YOU own the buffer the pointer is a reference to!

In order to dealloc the space the buffer is using, you need to call free() on it, and should probably set the pointer back to NULL when done.

A.

JRS

  • Guest
Re: IDLL
« Reply #12 on: December 13, 2010, 07:36:53 pm »
Quote
Right.  A POINTER.  A pointer to what? A memory location.  With no space allocated.

When you call strdup(), it's not returning a string, but a POINTER to a string buffer.  THAT'S what your passed pointer is now pointing to.

So, who owns that buffer?  YOU.  That's the point.

GTK-Server owns the buffer, I just send it a API (text) definition to process. GTK-Server processes Gtk calls the same way it process OS API calls.

I had to remove the Free stuff as I was getting GTK-Server tracebacks telling me I was trying to free an invalid pointer. My original code works flawlessly run after run with no memory corruption or complaints from either SB or GTK-Server. I have to assume at this point that GTK-Server is cleaning up after the API call I requested it make.

This is GOLD code and has worked perfectly since I created it. Trying to create a SB STRPTR() function and adding another level of pointers to the mix is asking too much of SB. IMHO

Code: [Select]
dsninfo = DLL("gdaui_login_get_connection_information " & login)
info_provider = 0
DLL("strncpy " & VARPTR(info_provider) & " " & dsninfo + 4 & " 4")
info_provider = DLL("strdup " & info_provider)
info_cnc = 0
DLL("strncpy " & VARPTR(info_cnc) & " " & dsninfo + 12 & " 4")
info_cnc = DLL("strdup " & info_cnc)

cnc = DLL("gda_connection_open_from_string " & info_provider & " " & info_cnc & " " & " 0 0 0")

« Last Edit: December 13, 2010, 07:43:09 pm by JRS »

JRS

  • Guest
Re: IDLL
« Reply #13 on: December 13, 2010, 08:20:54 pm »
Here is what I'm sticking with. You have a choice of calling methods and both work fine. (DLL or _DLL)

Code: Text
  1. ' GNOME-DB GRID
  2.  
  3. ' INTERFACE
  4. DECLARE SUB DLL ALIAS "_gtk" LIB "gtk-server"
  5. DECLARE SUB VARPTR ALIAS "varptr" LIB "gtk-server"
  6.  
  7. ' GDA4
  8. DLL("gtk_server_require libgda-4.0.so")
  9. DLL("gtk_server_require libgda-ui-4.0.so")
  10.  
  11. ' DECLARE
  12.  
  13. DLL("gtk_server_define gtk_init NONE NONE 2 NULL NULL")
  14. DLL("gtk_server_define gtk_dialog_new_with_buttons NONE WIDGET 8 STRING WIDGET INT STRING INT STRING INT NULL")
  15. DLL("gtk_server_define gdaui_login_new NONE WIDGET 1 STRING")
  16. DLL("gtk_server_define gtk_box_pack_start NONE NONE 5 WIDGET WIDGET BOOL BOOL INT")
  17. DLL("gtk_server_define gtk_dialog_get_content_area NONE WIDGET 1 WIDGET")
  18. DLL("gtk_server_define gtk_widget_show NONE NONE 1 WIDGET")
  19. DLL("gtk_server_define gtk_dialog_run delete-event INT 1 WIDGET")
  20. DLL("gtk_server_define gdaui_login_get_connection_information NONE WIDGET 1 WIDGET")
  21. DLL("gtk_server_define gda_connection_open_from_string NONE WIDGET 5 STRING STRING POINTER INT NULL")
  22. DLL("gtk_server_define gtk_widget_destroy NONE NONE 1 WIDGET")
  23. DLL("gtk_server_define gda_execute_select_command NONE WIDGET 3 WIDGET STRING NULL")
  24. DLL("gtk_server_define g_object_unref NONE NONE 1 WIDGET")
  25. DLL("gtk_server_define gtk_window_new delete-event WIDGET 1 INT")
  26. DLL("gtk_server_define gdaui_grid_new NONE WIDGET 1 WIDGET")
  27. DLL("gtk_server_define gtk_container_add NONE NONE 2 WIDGET WIDGET")
  28. DLL("gtk_server_define gtk_widget_show_all NONE NONE 1 WIDGET")
  29. DLL("gtk_server_define gtk_server_callback NONE STRING 1 STRING")
  30. DLL("gtk_server_define gtk_window_set_default_size NONE NONE 3 WIDGET INT INT")
  31. DLL("gtk_server_define gtk_window_set_title NONE NONE 2 WIDGET STRING")
  32. DLL("gtk_server_define strncpy NONE STRING 3 POINTER POINTER INT")
  33. DLL("gtk_server_define strdup NONE STRING 1 POINTER")
  34.  
  35.  
  36. CONST GTK_STOCK_CANCEL = "gtk-cancel"
  37. CONST GTK_STOCK_OK = "gtk-ok"
  38. CONST GTK_RESPONSE_NONE = -1
  39. CONST GTK_RESPONSE_OK = -5
  40. CONST GDA_CONNECTION_OPTIONS_NONE = 0
  41. CONST GTK_WINDOW_TOPLEVEL = 0
  42. CONST GTK_DIALOG_MODAL = 1
  43. CONST provider = 4
  44. CONST cnc_string = 12
  45.  
  46.  
  47. FUNCTION _DLL(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
  48. LOCAL arg_str
  49.   arg_str = STR(a0) & " " & STR(a1) & " " & STR(a2) & " " & STR(a3) & " " & STR(a4) & " " & STR(a5) & " " & STR(a6) & " " & STR(a7) & " " & STR(a8) & " " & STR(a9)
  50.   _DLL = DLL(arg_str)
  51. END FUNCTION
  52.  
  53.  
  54. SUB gtk_main
  55. LOCAL event
  56.  
  57. REPEAT
  58.   event = DLL("gtk_server_callback wait")
  59. UNTIL event = window
  60.  
  61. END SUB
  62.  

Code: Text
  1. ' GNOME-DB GRID
  2.  
  3. INCLUDE "gnome-db.sbh"
  4.  
  5. DLL("gtk_init 0 0")
  6. DLL("gdaui_init")
  7.  
  8. ' DB Control Window
  9. window = DLL("gtk_dialog_new_with_buttons \"Select the Data Source to connect to\" 0 " & GTK_DIALOG_MODAL & " " & GTK_STOCK_CANCEL & " " & GTK_RESPONSE_NONE & " " & GTK_STOCK_OK & " " & GTK_RESPONSE_OK & " 0")
  10. login = DLL("gdaui_login_new NULL")
  11. DLL("gtk_box_pack_start " & DLL("gtk_dialog_get_content_area " & window) & " " &  login & " TRUE TRUE 0")
  12. DLL("gtk_widget_show " & login)
  13. IF DLL("gtk_dialog_run " & window) <> GTK_RESPONSE_OK THEN
  14.   PRINT "Cancelled!\n"
  15.   END
  16. END IF
  17. dsninfo = DLL("gdaui_login_get_connection_information " & login)
  18. info_provider = 0
  19. DLL("strncpy " & VARPTR(info_provider) & " " & dsninfo + provider & " 4")
  20. info_provider = DLL("strdup " & info_provider)
  21. info_cnc = 0
  22. DLL("strncpy " & VARPTR(info_cnc) & " " & dsninfo + cnc_string  & " 4")
  23. info_cnc = DLL("strdup " & info_cnc)
  24. cnc = DLL("gda_connection_open_from_string " & info_provider & " " & info_cnc & " " & " 0 0 0")
  25. data_model = DLL("gda_execute_select_command " & cnc & " \"SELECT * FROM customers\" 0")
  26. DLL("gtk_widget_destroy " & window)
  27.  
  28. ' DB Data Grid
  29. window = DLL("gtk_window_new 0")
  30. DLL("gtk_window_set_title " & window & " \"GNOME-DB Grid Control Example\"")
  31. DLL("gtk_window_set_default_size " & window & " 400 200")
  32. grid = DLL("gdaui_grid_new " & data_model)
  33. DLL("g_object_unref " & data_model)
  34. DLL("gtk_container_add " & window & " " & grid)
  35. DLL("gtk_widget_show_all " & window)
  36.  
  37. gtk_main()
  38.  
  39. DLL("g_object_unref " & cnc)
  40.  

Code: Text
  1. ' GNOME-DB GRID
  2.  
  3. INCLUDE "gnome-db.sbh"
  4.  
  5. _DLL("gtk_init", 0, 0)
  6. _DLL("gdaui_init")
  7.  
  8. ' DB Control Window
  9. window = _DLL("gtk_dialog_new_with_buttons","\"Select the Data Source to connect to\"", 0, GTK_DIALOG_MODAL, GTK_STOCK_CANCEL, GTK_RESPONSE_NONE, GTK_STOCK_OK, GTK_RESPONSE_OK, 0)
  10. login = _DLL("gdaui_login_new", "NULL")
  11. _DLL("gtk_box_pack_start", _DLL("gtk_dialog_get_content_area", window), login, TRUE, TRUE, 0)
  12. _DLL("gtk_widget_show", login)
  13. IF _DLL("gtk_dialog_run", window) <> GTK_RESPONSE_OK THEN
  14.   PRINT "Cancelled!\n"
  15.   END
  16. END IF
  17. dsninfo = _DLL("gdaui_login_get_connection_information", login)
  18. info_provider = 0
  19. _DLL("strncpy", VARPTR(info_provider), dsninfo + provider, 4)
  20. info_provider = _DLL("strdup", info_provider)
  21. info_cnc = 0
  22. _DLL("strncpy", VARPTR(info_cnc), dsninfo + cnc_string, 4)
  23. info_cnc = _DLL("strdup", info_cnc)
  24. cnc = _DLL("gda_connection_open_from_string", info_provider, info_cnc, 0, 0, 0)
  25. data_model = _DLL("gda_execute_select_command", cnc, "\"SELECT * FROM customers\"", 0)
  26. _DLL("gtk_widget_destroy", window)
  27.  
  28. ' DB Data Grid
  29. window = _DLL("gtk_window_new", 0)
  30. _DLL("gtk_window_set_title", window, "\"GNOME-DB Grid Control Example\"")
  31. _DLL("gtk_window_set_default_size", window, 400, 200)
  32. grid = _DLL("gdaui_grid_new", data_model)
  33. _DLL("g_object_unref", data_model)
  34. _DLL("gtk_container_add", window, grid)
  35. _DLL("gtk_widget_show_all", window)
  36.  
  37. gtk_main()
  38.  
  39. _DLL("g_object_unref", cnc)
  40.  
« Last Edit: December 13, 2010, 08:22:46 pm by JRS »

AIR

  • Guest
Re: IDLL
« Reply #14 on: December 13, 2010, 08:36:55 pm »
I can see that you are unwilling or unable to understand what I am saying, so I won't bother repeating.

Best of luck with this....