fonction d'une dll appellée par une fonction ... et plantage

Sujets variés concernant le développement en PureBasic
leo.cd
Messages : 15
Inscription : lun. 24/avr./2006 20:41

fonction d'une dll appellée par une fonction ... et plantage

Message par leo.cd »

Code : Tout sélectionner

Global ode_lib = OpenLibrary(#PB_Any, "ode.dll")

ProcedureDLL ode_dWorldDestroy(dWorldID)
  CallFunction(ode_lib, "dWorldDestroy", dWorldID)
EndProcedure
 
ode_dWorldDestroy(dWorldID)
Quand je fait ca j'ai l'erreur suivante pour la ligne

Code : Tout sélectionner

EndProcedure
Invalid memory access
alors que ça ca marche nikel :

Code : Tout sélectionner

Global ode_lib = OpenLibrary(#PB_Any, "ode.dll")

CallFunction(ode_lib, "dWorldDestroy", dWorldID)
et ça aussi :

Code : Tout sélectionner

Global ode_lib = OpenLibrary(#PB_Any, "ode.dll")

ProcedureDLL ode_dWorldCreate()
  dWorldID = CallFunction(ode_lib, "dWorldCreate")
  ProcedureReturn dWorldID
EndProcedure
 
ode_dWorldCreate()
Le problème semble être lié à une fonction dll avec un ou plusieurs arguments appellée dans une fonction.

note : même problème avec Procedure

C'est un bug déjà connu ? ou il y a une erreur de ma part ou une solution rationnelle ?
tmyke
Messages : 1554
Inscription : lun. 24/juil./2006 6:44
Localisation : vosges (France) 47°54'39.06"N 6°20'06.39"E

Re: fonction d'une dll appellée par une fonction ... et plan

Message par tmyke »

leo.cd a écrit :

Code : Tout sélectionner

Global ode_lib = OpenLibrary(#PB_Any, "ode.dll")

ProcedureDLL ode_dWorldDestroy(dWorldID)
  CallFunction(ode_lib, "dWorldDestroy", dWorldID)
EndProcedure
 
ode_dWorldDestroy(dWorldID)
En fait tu créé une DLL qui contient des appel de fonction ODE ?

(sinon essais ProcedureCDLL)

Ce genre de prob viens du fait que PB travaille en convention d'appel "stdcall"
alors que la plupart des pgm sous windows (et donc les DLL, comme ODE) travaillent
en convention d'appel "cdecl". D'ou un soucis au niveau de la pile, surtout
au moment de l'execution de 'endprocedure' sous PB
Force et sagesse...
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Re: fonction d'une dll appellée par une fonction ... et plan

Message par Flype »

tmyke a écrit :(sinon essais ProcedureCDLL)
et CallCFunction() / CallCFunctionFast().
leo.cd
Messages : 15
Inscription : lun. 24/avr./2006 20:41

Message par leo.cd »

Code : Tout sélectionner

Procedure kill(id)
  dWorldDestroy(id)
EndProcedure
même problème que ce soit Procedure, ProcedureDLL ou ProcedureCDLL ...

Je ne cherche pas à créer unde DLL mais simplement une application utilisant ODE et Dreamotion sous Pure Basic. Et ça marche bien jusqu'à qu'une fonction ode se trouve dans une de mes fonctions, ou qu'une fonction ODE appelle une des miennes. Ce qui est necessaire pour les collisions. Et puis ca me gène pour la suite de ne pas pouvoir utiliser les fonctions ODE dans d'autres fonctions ...

je déclare mes fonctions ODE de la manière suivante :

Code : Tout sélectionner

Prototype ode_dWorldDestroy(dWorldID)
Global ode_dWorldDestroy.ode_dWorldDestroy = GetFunction(ode_lib, "dWorldDestroy")
La dll de ODE est chargé avec l'id ode_lib :

Code : Tout sélectionner

Global ode_lib = OpenLibrary(#PB_Any, "ode.dll")
Donc toujours le même problème : Invalid memory access, et toujours pas de solutions ...

@ Flype : CallCFunction() / CallCFunctionFast() ce serait pour appeller la fonction ODE, et ca je le fait comme je l'ai mis plus haut, mon problème c'est d'appeller une fonction ODE depuis une fonction de mon programme.
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

et on peut la choper où ta dll - pour essayer ?
leo.cd
Messages : 15
Inscription : lun. 24/avr./2006 20:41

ODE

Message par leo.cd »

telecharger le rar (source + dll)

Code : Tout sélectionner

IncludeFile "ode.pb"

Global idW = dWorldCreate()

dWorldSetGravity(idW, 0, -9.8, 0)

kill(idW)

Code : Tout sélectionner

Structure v3d

  x.f
  y.f
  z.f

EndStructure

Global ode_lib = OpenLibrary(#PB_Any, "ode.dll") 

Prototype dWorldCreate()
dWorldCreate.dWorldCreate = GetFunction(ode_lib, "dWorldCreate")


Prototype dWorldSetGravity(idW, x.f, y.f, z.f)
Global dWorldSetGravity.dWorldSetGravity = GetFunction(ode_lib, "dWorldSetGravity")

Prototype dWorldGetGravity(idW, *g)
dWorldGetGravity.dWorldGetGravity = GetFunction(ode_lib, "dWorldGetGravity")

Prototype dWorldDestroy(dWorldID)
Global dWorldDestroy.dWorldDestroy = GetFunction(ode_lib, "dWorldDestroy")

Procedure kill(id)
  dWorldDestroy(id)
EndProcedure
Dernière modification par leo.cd le mer. 04/avr./2007 11:05, modifié 1 fois.
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

ok, j'ai testé et je ne vois pas de probleme particulier avec cette dll.
il s'agit d'une mauvaise utilisation. j'ai corrigé comme çà vite fait.

le fichier include 'ode.pbi'

Code : Tout sélectionner


;--
;-- ODE.DLL API
;--


Structure v3d
  x.f
  y.f
  z.f
EndStructure


Prototype dWorldCreate()
Prototype dWorldSetGravity(idW.l, x.f, y.f, z.f)
Prototype dWorldGetGravity(idW.l, *g)
Prototype dWorldDestroy(idW.l)


Define ode_lib.l = OpenLibrary(#PB_Any, "ode.dll") 


If Not ode_lib
  MessageRequester("Error", "Can't initialize the library `ode.dll` !", #MB_ICONERROR) : End
EndIf


Global dWorldCreate.dWorldCreate         = GetFunction(ode_lib, "dWorldCreate")
Global dWorldSetGravity.dWorldSetGravity = GetFunction(ode_lib, "dWorldSetGravity")
Global dWorldGetGravity.dWorldGetGravity = GetFunction(ode_lib, "dWorldGetGravity")
Global dWorldDestroy.dWorldDestroy       = GetFunction(ode_lib, "dWorldDestroy")


;--
;-- Vérifie si les fonctions sont bien initialisées.
;--


Debug "======================" 
Debug dWorldCreate
Debug dWorldSetGravity
Debug dWorldGetGravity
Debug dWorldDestroy
Debug "======================"


et le fichier test 'main.pb'

Code : Tout sélectionner

IncludeFile "ode.pbi"

Define world.l, gravity.v3d

world = dWorldCreate()

If world
  
  dWorldSetGravity(world, 2.33, -9.8, 0.165)
  
  If dWorldGetGravity (world, @gravity)
    Debug StrF(gravity\x, 3)
    Debug StrF(gravity\y, 3)
    Debug StrF(gravity\z, 3)
  EndIf
  
  dWorldDestroy(world)
  
EndIf

Le truc c'est que tu as déclaré dans le désordre la globale idW.
Si la globale idW est utilisée dans l'include ode.pbi mais que tu la déclare dans main.pb, purebasic ne saura pas qu'il s'agit d'une globale dans l'include.

Bien plus important encore,
Pourquoi détruire le world avec kill() AVANT d'utiliser la fonction GetGravity() ???
C'est clair que là cà plante puisque tu sollicites une fonction qui nécessite que le monde soit créé, or tu le détruit juste avant.
leo.cd
Messages : 15
Inscription : lun. 24/avr./2006 20:41

Message par leo.cd »

Code : Tout sélectionner

Procedure dWorldDestroy2(world)

  dWorldDestroy(world) 
  
EndProcedure
ajoute cette fonction a la fin de ode.pbi


et dans le main fait :

Code : Tout sélectionner

dWorldDestroy2(world)
à la place de :

Code : Tout sélectionner

dWorldDestroy(world)
et la tu veras quel est mon problème ...

Ca n'a aucun interet de mettre une fonction dans une fonction mais l'a j'ai simplifié mon code (ode.pb fait 1500 lignes), je veux pouvoir faire des fonctions qui vont appeller plusieurs fonctions ode.
Le truc c'est que tu as déclaré dans le désordre la globale idW.
La seule fonction qui utilisait idW je ne l'utilisait pas dans l'exemple.
Pourquoi détruire le world avec kill() AVANT d'utiliser la fonction GetGravity() ???
Une erreur négligeable car le programme plante avant, lors de l'utilisation de kill(), fonction que tu as supprimé de ton code, donc forcément ca marche, mais ca résoud pas mon problème ^^

Tmyke semble avoir bien cerné le problème mais sa suggéstion ne marche pas non plus ... je vais essayer de trouver des infos sur les conventions d'appel de fonctions.
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

ok j'ai bien compris ton problème, excuse pour la lenteur d'esprit.

en tout cas moi j'y arrive par 2 méthodes différentes :

1/ en utilisant PrototypeC.l

2/ en utilisant CallCFunctionFast()

Code : Tout sélectionner

;--
;-- ODE.DLL API
;--


Structure v3d
  x.f
  y.f
  z.f
EndStructure


PrototypeC.l dWorldCreate()
PrototypeC.l dWorldSetGravity(world.l, x.f, y.f, z.f)
PrototypeC.l dWorldGetGravity(world.l, *gravity)
PrototypeC.l dWorldDestroy(world.l)


Global ode_lib.l = OpenLibrary(#PB_Any, "ode.dll") 


If Not ode_lib
  MessageRequester("Error", "Can't initialize the library `ode.dll` !", #MB_ICONERROR) : End
EndIf


Global dWorldCreate.dWorldCreate         = GetFunction(ode_lib, "dWorldCreate")
Global dWorldSetGravity.dWorldSetGravity = GetFunction(ode_lib, "dWorldSetGravity")
Global dWorldGetGravity.dWorldGetGravity = GetFunction(ode_lib, "dWorldGetGravity")
Global dWorldDestroy.dWorldDestroy       = GetFunction(ode_lib, "dWorldDestroy")


;--
;-- Vérifie si les fonctions sont bien initialisées.
;--


Debug "======================" 
Debug dWorldCreate
Debug dWorldSetGravity
Debug dWorldGetGravity
Debug dWorldDestroy
Debug "======================"


;--
;-- Fonctions perso.
;--

Procedure.l dWorldCreate2()
  
  ProcedureReturn dWorldCreate()
  ;ProcedureReturn CallCFunctionFast(dWorldCreate)
  
EndProcedure
Procedure.l dWorldSetGravity2(world.l, x.f, y.f, z.f)
  
  ProcedureReturn dWorldSetGravity(world, x, y, z)
  ;ProcedureReturn CallCFunctionFast(dWorldSetGravity, world, x, y, z)
  
EndProcedure
Procedure.l dWorldGetGravity2(world.l, *gravity)
  
  ProcedureReturn dWorldGetGravity(world, *gravity)
  ;ProcedureReturn CallCFunctionFast(dWorldGetGravity, world, *gravity)
  
EndProcedure
Procedure.l dWorldDestroy2(world.l)
  
  ProcedureReturn dWorldDestroy(world)
  ;ProcedureReturn CallCFunctionFast(dWorldDestroy, world)
  
EndProcedure
et

Code : Tout sélectionner

IncludeFile "ode.pbi"

Define world.l, gravity.v3d

world = dWorldCreate2()

If world
  
  dWorldSetGravity2(world, 2.33, -9.8, 0.165)
  
  If dWorldGetGravity2(world, @gravity)
    Debug StrF(gravity\x, 3)
    Debug StrF(gravity\y, 3)
    Debug StrF(gravity\z, 3)
  EndIf
  
  dWorldDestroy2(world)
  
EndIf
leo.cd
Messages : 15
Inscription : lun. 24/avr./2006 20:41

merci

Message par leo.cd »

Youpiii !!!

C'est peut être lent mais ça en faut la peine :wink:

merci beaucoup.

Je posterais mon code une fois plus avancé et je pense faire quelques tutos pour utiliser ode avec PureBasic.
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

c'est pas pour faire mon kakou, mais n'empêche que dès mon 1er post j'avais raison :twisted:

content de t'aider en tout cas.

au fait c'est quoi ODE, une bibliothèque physique ?
leo.cd
Messages : 15
Inscription : lun. 24/avr./2006 20:41

Message par leo.cd »

C'est vrai ^^

C'est ce fameux 'C' qui change tout ... je savais pas que prototypeC existait aussi, donc j'ai pas essayer ça.

Oui c'est un moteur physique : www.ode.org

Open Dynamic Engine

J'arrive a faire tomber une boule, et j'ai presque fini de la faire réagir avec le sol.
leo.cd
Messages : 15
Inscription : lun. 24/avr./2006 20:41

Question HS

Message par leo.cd »

J'ai une question HS, mais comme j'ai commencé ici je continue :

dans la doc de ode je rencontre souvent le type de variables int, ca corespond à quoi en PureBasic ? et surtout : combien d'octets ca prend ?
minirop
Messages : 321
Inscription : mer. 02/août/2006 21:06

Message par minirop »

4 sur un proc 32 bits donc c'est .l
Avatar de l’utilisateur
Flype
Messages : 2431
Inscription : jeu. 29/janv./2004 0:26
Localisation : Nantes

Message par Flype »

je confirme pour 4 octets.
Répondre