wraper für c funktion mit Struktur als rückgabe wert

Für allgemeine Fragen zur Programmierung mit PureBasic.
Caliban
Beiträge: 41
Registriert: 08.09.2004 08:46

Re: wraper für c funktion mit Struktur als rückgabe wert

Beitrag von Caliban »

Habe meinen Fehler gefunden, nur verstehe ich es nicht. Mach ich aus der Procedure handle_keys() ein Macro dann funktioniert es.
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: wraper für c funktion mit Struktur als rückgabe wert

Beitrag von Danilo »

Probiere mal das mit der libtcod-vs.dll (die mingw crasht):

Code: Alles auswählen

;Nach Tutorial auf Roguelike Basein
;http://roguebasin.roguelikedevelopment.org/index.php/Complete_Roguelike_Tutorial,_using_python

CompilerIf #PB_Compiler_Unicode
    CompilerError "unicode ausschalten"
CompilerEndIf

;- Definition
Structure TCOD_key_t  
  vk.l
  c.b
  pressed.b
  lalt.b
  lctrl.b
  ralt.b
  rctrl.b
  shift.b
  PB_Align(0,1)
EndStructure

#FONT_TYPE_GREYSCALE=4
#FONT_LAYOUT_TCOD=8
#KEY_ENTER = 4
#KEY_ESCAPE = 1

PrototypeC   TCOD_console_set_custom_font(fontFile.p-ascii, flags.l, nb_char_horiz.l, nb_char_vertic.l)
PrototypeC   TCOD_console_init_root(w.i,h.i,title.p-ascii,fullscreen.b)
PrototypeC   TCOD_console_is_window_closed()
PrototypeC   TCOD_console_set_foreground_color(con.i,col.i)
PrototypeC   TCOD_console_print_left(con.i,x.i,y.i,flag.i, fmt.p-ascii)
PrototypeC   TCOD_console_flush()
PrototypeC   TCOD_console_is_key_pressed(key.i)
PrototypeC   TCOD_console_set_fullscreen(fullscreen.b)
PrototypeC   TCOD_console_is_fullscreen()
PrototypeC   TCOD_console_check_for_keypress(*pointer.TCOD_key_t,flags.l)
PrototypeC   TCOD_console_wait_for_keypress(*ret.TCOD_key_t,flush.b)
PrototypeC   TCOD_console_delete(console.i)
PrototypeC.i TCOD_console_new(w.l, h.l)

;libtcod = OpenLibrary(#PB_Any,"libtcod-vs.dll")
libtcod = OpenLibrary(#PB_Any,"libtcod-vs.dll")
If libtcod <> 0
  Global TCOD_console_set_custom_font.TCOD_console_set_custom_font = GetFunction(libtcod,"TCOD_console_set_custom_font")
  Global TCOD_console_init_root.TCOD_console_init_root = GetFunction(libtcod,"TCOD_console_init_root")
  Global TCOD_console_is_window_closed.TCOD_console_is_window_closed = GetFunction(libtcod,"TCOD_console_is_window_closed")
  Global TCOD_console_set_foreground_color.TCOD_console_set_foreground_color = GetFunction(libtcod,"TCOD_console_set_foreground_color")
  Global TCOD_console_print_left.TCOD_console_print_left = GetFunction(libtcod,"TCOD_console_print_left")
  Global TCOD_console_flush.TCOD_console_flush = GetFunction(libtcod,"TCOD_console_flush")
  Global TCOD_console_is_key_pressed.TCOD_console_is_key_pressed = GetFunction(libtcod,"TCOD_console_is_key_pressed")
  Global TCOD_console_set_fullscreen.TCOD_console_set_fullscreen = GetFunction(libtcod,"TCOD_console_set_fullscreen")
  Global TCOD_console_is_fullscreen.TCOD_console_is_fullscreen = GetFunction(libtcod,"TCOD_console_is_fullscreen")
  Global TCOD_console_check_for_keypress.TCOD_console_check_for_keypress = GetFunction(libtcod,"TCOD_console_check_for_keypress")     
  Global TCOD_console_wait_for_keypress.TCOD_console_wait_for_keypress = GetFunction(libtcod,"TCOD_console_wait_for_keypress")
  Global TCOD_console_new.TCOD_console_new = GetFunction(libtcod,"TCOD_console_new")
  Global TCOD_console_delete.TCOD_console_delete = GetFunction(libtcod,"TCOD_console_delete")
Else
  MessageRequester("Fehler","libtcod-vs.dll konnte nicht geladen werden.")
  End
EndIf

Procedure handle_keys()
  Shared playerx, playery
  
  key.TCOD_key_t
  TCOD_console_wait_for_keypress(@key,#True)
  Debug key\vk
  
  ;alt+enter toggle fullscreen
  If key\vk = #KEY_ENTER And key\lalt
    TCOD_console_set_fullscreen(~(TCOD_console_is_fullscreen()))
  ElseIf key\vk = #KEY_ESCAPE
    ProcedureReturn #True
  EndIf 
  
EndProcedure

;-Hauptprogramm
#SCREEN_WIDTH = 80
#SCREEN_HEIGHT = 50

playerx = #SCREEN_WIDTH/2
playery = #SCREEN_HEIGHT/2

If FileSize("arial10x10.png")>0
    TCOD_console_set_custom_font("arial10x10.png", #FONT_TYPE_GREYSCALE | #FONT_LAYOUT_TCOD,0,0)
EndIf
TCOD_console_init_root(#SCREEN_WIDTH, #SCREEN_HEIGHT, "libtcod PB Wraper", #False)


While TCOD_console_is_window_closed()&$FF = #False
  
   TCOD_console_set_foreground_color(0, RGB(255,255,255))
   TCOD_console_print_left(0, playerx, playery, 0, "abc")
   
   TCOD_console_flush()
   
   TCOD_console_print_left(0, playerx, playery, 0, "cde")
   
   ;handle keys And exit If needed
   exit = handle_keys()

   If exit : Break  : EndIf 
   
Wend

TCOD_console_delete(0)

CloseLibrary(libtcod)
Was ich geändert habe:
- PrototypeC für alles!
- statt string.s immer string.p-ascii deklarieren
- TCOD_console_is_window_closed()&$FF, da diese funktion ein bool (byte) zurück gibt. Die anderen Bits sind undefiniert.
- prüfen ob "arial10x10.png" vorhanden ist, sonst crash
- am Ende TCOD_console_delete(0) aufrufen zum beenden

Ich kenne die mingw aufrufkonventionen für die versteckkte Rückgabestruktur nicht.
Kannst Du nicht die VS DLL nehmen? Damit läuft das hier mit und ohne Debugger und
beendet sich auch richtig.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: wraper für c funktion mit Struktur als rückgabe wert

Beitrag von Danilo »

Gleicher Code mit der libtcode-mingw.dll:

Code: Alles auswählen

;Nach Tutorial auf Roguelike Basein
;http://roguebasin.roguelikedevelopment.org/index.php/Complete_Roguelike_Tutorial,_using_python

CompilerIf #PB_Compiler_Unicode
    CompilerError "unicode ausschalten"
CompilerEndIf

;- Definition
Structure TCOD_key_t  
  vk.l
  c.b
  pressed.b
  lalt.b
  lctrl.b
  ralt.b
  rctrl.b
  shift.b
  PB_Align(0,1)
EndStructure

#FONT_TYPE_GREYSCALE=4
#FONT_LAYOUT_TCOD=8
#KEY_ENTER = 4
#KEY_ESCAPE = 1

PrototypeC   TCOD_console_set_custom_font(fontFile.p-ascii, flags.l, nb_char_horiz.l, nb_char_vertic.l)
PrototypeC   TCOD_console_init_root(w.i,h.i,title.p-ascii,fullscreen.b)
PrototypeC   TCOD_console_is_window_closed()
PrototypeC   TCOD_console_set_foreground_color(con.i,col.i)
PrototypeC   TCOD_console_print_left(con.i,x.i,y.i,flag.i, fmt.p-ascii)
PrototypeC   TCOD_console_flush()
PrototypeC   TCOD_console_is_key_pressed(key.i)
PrototypeC   TCOD_console_set_fullscreen(fullscreen.b)
PrototypeC   TCOD_console_is_fullscreen()
PrototypeC   TCOD_console_delete(console.i)
PrototypeC.i TCOD_console_new(w.l, h.l)

Prototype    TCOD_console_wait_for_keypress(*ret.TCOD_key_t,flush.b)
Prototype    TCOD_console_check_for_keypress(*pointer.TCOD_key_t,flags.l)


libtcod = OpenLibrary(#PB_Any,"libtcod-mingw.dll")
;libtcod = OpenLibrary(#PB_Any,"libtcod-vs.dll")
If libtcod <> 0
  Global TCOD_console_set_custom_font.TCOD_console_set_custom_font = GetFunction(libtcod,"TCOD_console_set_custom_font")
  Global TCOD_console_init_root.TCOD_console_init_root = GetFunction(libtcod,"TCOD_console_init_root")
  Global TCOD_console_is_window_closed.TCOD_console_is_window_closed = GetFunction(libtcod,"TCOD_console_is_window_closed")
  Global TCOD_console_set_foreground_color.TCOD_console_set_foreground_color = GetFunction(libtcod,"TCOD_console_set_foreground_color")
  Global TCOD_console_print_left.TCOD_console_print_left = GetFunction(libtcod,"TCOD_console_print_left")
  Global TCOD_console_flush.TCOD_console_flush = GetFunction(libtcod,"TCOD_console_flush")
  Global TCOD_console_is_key_pressed.TCOD_console_is_key_pressed = GetFunction(libtcod,"TCOD_console_is_key_pressed")
  Global TCOD_console_set_fullscreen.TCOD_console_set_fullscreen = GetFunction(libtcod,"TCOD_console_set_fullscreen")
  Global TCOD_console_is_fullscreen.TCOD_console_is_fullscreen = GetFunction(libtcod,"TCOD_console_is_fullscreen")
  Global TCOD_console_check_for_keypress.TCOD_console_check_for_keypress = GetFunction(libtcod,"TCOD_console_check_for_keypress")     
  Global TCOD_console_wait_for_keypress.TCOD_console_wait_for_keypress = GetFunction(libtcod,"TCOD_console_wait_for_keypress")
  Global TCOD_console_new.TCOD_console_new = GetFunction(libtcod,"TCOD_console_new")
  Global TCOD_console_delete.TCOD_console_delete = GetFunction(libtcod,"TCOD_console_delete")
Else
  MessageRequester("Fehler","libtcod-mingw.dll konnte nicht geladen werden.")
  End
EndIf

Procedure handle_keys()
  Shared playerx, playery
  
  key.TCOD_key_t
  TCOD_console_wait_for_keypress(@key,#True)
  !add esp,4
  
  Debug key\vk
  
  ;alt+enter toggle fullscreen
  If key\vk = #KEY_ENTER And key\lalt
    TCOD_console_set_fullscreen(~(TCOD_console_is_fullscreen()))
  ElseIf key\vk = #KEY_ESCAPE
    ProcedureReturn #True
  EndIf 
  
EndProcedure

;-Hauptprogramm
#SCREEN_WIDTH = 80
#SCREEN_HEIGHT = 50

playerx = #SCREEN_WIDTH/2
playery = #SCREEN_HEIGHT/2

If FileSize("arial10x10.png")>0
    TCOD_console_set_custom_font("arial10x10.png", #FONT_TYPE_GREYSCALE | #FONT_LAYOUT_TCOD,0,0)
EndIf
TCOD_console_init_root(#SCREEN_WIDTH, #SCREEN_HEIGHT, "libtcod PB Wraper", #False)


While TCOD_console_is_window_closed()&$FF = #False
  
   TCOD_console_set_foreground_color(0, RGB(255,255,255))
   TCOD_console_print_left(0, playerx, playery, 0, "abc")
   
   TCOD_console_flush()
   
   TCOD_console_print_left(0, playerx, playery, 0, "cde")
   
   ;handle keys And exit If needed
   exit = handle_keys()

   If exit : Break  : EndIf 
   
Wend

TCOD_console_delete(0)

CloseLibrary(libtcod)
Der Unterschied zur VC++ DLL (libtcode-vs) ist nur die Aufrufkonvention bei Struktur-Rückgabe,
also mit dem versteckten Struktur-Pointer.
In diesem Code sind die 2 Prototypen als Prototype (ohne C!) deklariert. Dafür muß man
direkt nach dem Aufruf dieser Funktionen den Stack durch "!add esp,4" korrigieren.
In der VC++ Variante ist das nicht nötig.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Caliban
Beiträge: 41
Registriert: 08.09.2004 08:46

Re: wraper für c funktion mit Struktur als rückgabe wert

Beitrag von Caliban »

Vielen Dank Danilo für die Hilfe!
Funktioniert jetzt alles einwandfrei, verwende jetzt die Vlibtcod-VS.dll. Und ich denke ich hab auch etwas dazugelern.
Benutzeravatar
Danilo
-= Anfänger =-
Beiträge: 2284
Registriert: 29.08.2004 03:07

Re: wraper für c funktion mit Struktur als rückgabe wert

Beitrag von Danilo »

Kein Problem, und Danke auch an Dich - kannte die Lib noch nicht. :)

Möchtest Du das dann hier veröffentlichen, wenn Du den Import oder Wrapper
fertig hast? Interessante Lib - sicherlich nicht schlecht, wenn man das im Lager hat.
cya,
...Danilo
"Ein Genie besteht zu 10% aus Inspiration und zu 90% aus Transpiration" - Max Planck
Caliban
Beiträge: 41
Registriert: 08.09.2004 08:46

Re: wraper für c funktion mit Struktur als rückgabe wert

Beitrag von Caliban »

Ja, habe fest vor das hier zu veröffentlichen. Primär gedacht ist sie ja für Roguelikes aber sicher auch zu gebrauchen wenn man Text sonstwie etwas aufwendiger anzeigen möchte.
Caliban
Beiträge: 41
Registriert: 08.09.2004 08:46

Re: wraper für c funktion mit Struktur als rückgabe wert

Beitrag von Caliban »

Hab jetzt wieder ein Problem mit der Lib mit folgenden Code zum testen. Villeicht hat ja woeder wer einen Tipp?

Code: Alles auswählen

PrototypeC   TCOD_random_get_instance()
PrototypeC   TCOD_random_new(algo.i = 0)
PrototypeC.i TCOD_random_get_int(mersenne.i, min.i, max.i)

PrototypeC   TCOD_namegen_parse (filename.p-ascii, random.i = #Null)
PrototypeC.s TCOD_namegen_generate (name.p-ascii, allocate.i = #False); allocate is bool


libtcod = OpenLibrary(#PB_Any,"libtcod-vs.dll")
If libtcod <> 0
  TCOD_random_get_instance.TCOD_random_get_instance = GetFunction(libtcod, "TCOD_random_get_instance")
  TCOD_random_new.TCOD_random_new = GetFunction(libtcod, "TCOD_random_new")
  TCOD_random_get_int.TCOD_random_get_int = GetFunction(libtcod, "TCOD_random_get_int")
  
  TCOD_namegen_parse .TCOD_namegen_parse  = GetFunction(libtcod, "TCOD_namegen_parse ")
  TCOD_namegen_generate .TCOD_namegen_generate  = GetFunction(libtcod, "TCOD_namegen_generate ")
    
  TCOD_random_new()
  Debug TCOD_random_get_int(TCOD_random_get_instance(),0,10) ; das funktioniert
  
  If FileSize("jice_fantasy.cfg") > 0
    ;hier kommt Invalid memory access
    TCOD_namegen_parse("jice_fantasy.cfg",TCOD_random_get_instance()) 
    Debug TCOD_namegen_generate("Fantasy male")
  EndIf  
EndIf
hier die benötigte jice_fantasy.cfg Datei:

Code: Alles auswählen

//Fantasy names from Jice's "The Cave"
name "Fantasy male" {
  syllablesStart = "Aer, An, Ar, Ban, Bar, Ber, Beth, Bett, Cut, Dan, Dar, Dell, Der, Edr, Er, Eth, Ett, Fin, Ian, Iarr, Ill, Jed, Kan, Kar, Ker, Kurr, Kyr, Man, Mar, Mer, Mir, Tsal, Tser, Tsir, Van, Var, Yur, Yyr"
  syllablesMiddle = "al, an, ar, el, en, ess, ian, onn, or"
  syllablesEnd = "ai, an, ar, ath, en, eo, ian, is, u, or"
  illegal = "orar, arrar"
  rules = "$s$m$e, $s$e"
}

name "Fantasy female" {
  syllablesStart = "Aer, An, Ar, Ban, Bar, Ber, Beth, Bett, Cut, Dan, Dar, Dell, Der, Edr, Er, Eth, Ett, Fin, Ian, Iarr, Ill, Jed, Kan, Kar, Ker, Kurr, Kyr, Man, Mar, Mer, Mir, Tsal, Tser, Tsir, Van, Var, Yur, Yyr"
  syllablesMiddle = "al, an, ar, el, en, ess, ian, onn, or"
  syllablesEnd = "a, ae, aelle, ai, ea, i, ia, u, wen, wyn"
  illegal = "arrar"
  rules = "$s$m$e, $s$e"
}

ein Auszug aus der Header Datei namegen.h

Code: Alles auswählen

/* parse a file with syllable sets */
TCODLIB_API void TCOD_namegen_parse (const char * filename, TCOD_random_t random);
/* generate a name */
TCODLIB_API char * TCOD_namegen_generate (char * name, bool allocate);
/* generate a name using a custom generation rule */
TCODLIB_API char * TCOD_namegen_generate_custom (char * name, char * rule, bool allocate);
/* retrieve the list of all available syllable set names */
TCODLIB_API TCOD_list_t TCOD_namegen_get_sets (void);
/* delete a generator */
TCODLIB_API void TCOD_namegen_destroy (void);
Antworten