API non enregistrée

Archive.
popstatic
Messages : 83
Inscription : lun. 20/sept./2004 18:21
Localisation : derriere toi fais gaffe!

API non enregistrée

Message par popstatic »

l'api suivante
BOOL WINAPI ReadDirectoryChangesW(
__in HANDLE hDirectory,
__out LPVOID lpBuffer,
__in DWORD nBufferLength,
__in BOOL bWatchSubtree,
__in DWORD dwNotifyFilter,
__out_opt LPDWORD lpBytesReturned,
__inout_opt LPOVERLAPPED lpOverlapped,
__in_opt LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
ne passe pas au compilateur
---------------------------
PureBasic
---------------------------
Ligne 38: ReadDirectoryChangesW_() is not a function, array, macro or linked list
---------------------------
OK
---------------------------
[/code]
Asus bien? asus tres bien!
Avatar de l’utilisateur
Progi1984
Messages : 2659
Inscription : mar. 14/déc./2004 13:56
Localisation : France > Rennes
Contact :

Message par Progi1984 »

et ReadDirectoryChanges_ ?
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

Deux remarques sur les API

1) Toutes les API ne sont pas déclarées sous PB, il y en a tellement

2) Pour celles déclarées, normalement, il n'y a pas besoin d'utiliser la version Unicode ou ASCII de l'API ni même des structures, PB le fait automatiquement à la compilation en fonction du mode unicode ou non. Certaines API utilisent des chaînes unicode même si elle sont compilées en mode ASCII, il faut à ce moment déclarer les chaînes en unicode

Voici l'extrait de la doc PB
Unicode et Windows

Sous Windows, en mode unicode, PureBasic utilise l'encodage UCS2 qui est le format utilisé de manière interne par l'API, donc aucune conversion n'est nécessaire lorsqu'un fonction est appelée. Si le programme utilise des fonctions API, PureBasic utilisera automatiquement la version unicode de la fonction si elle est disponible (par exemple MessageBox_() pointera vers MessageBoxW() en mode unicode, et vers MessageBoxA() en mode ascii). Il en va de même pour toutes les structures et les constantes API supportées par PureBasic. Ainsi il est possible d'utiliser le même code source API et de le compiler en mode ascii ou unicode sans aucun changement.

Unicode est supporté nativement uniquement sur Windows NT et supérieur (Windows 2000/XP/Vista): un programme unicode ne fonctionnera pas sur Windows 95/98/NT. Il y a une solution qui consiste à utiliser la dll 'unicows' mais elle n'est pas gérée par PureBasic pour l'instant. Si le programme doit fonctionner sur Win 9x, le mieux est de fournir deux versions de l'exécutable: un en mode ascii et l'autre en mode unicode. Comme il faut uniquement spécifier une option de compilation pour passer du mode ascii au mode unicode, ça devrait être aisé.
A+
Denis
popstatic
Messages : 83
Inscription : lun. 20/sept./2004 18:21
Localisation : derriere toi fais gaffe!

Message par popstatic »

@progi1984: ReadDirectoryChanges_ (sans le W) n'existe pas dans l'API windows.
@Denis:
1) Certes toutes les API ne sont pas déclrée dans PB, je comprends. Seulement comment compiler un programme qui les utilisent??
Elles ne sont pas déclarées donc "tant pis on les utilise pas"?
2) okip c'est noté pour l'ASCII/UNICODE
Asus bien? asus tres bien!
Anonyme2
Messages : 3518
Inscription : jeu. 22/janv./2004 14:31
Localisation : Sourans

Message par Anonyme2 »

popstatic a écrit :@progi1984: ReadDirectoryChanges_ (sans le W) n'existe pas dans l'API windows.
@Denis:
1) Certes toutes les API ne sont pas déclrée dans PB, je comprends. Seulement comment compiler un programme qui les utilisent??
Elles ne sont pas déclarées donc "tant pis on les utilise pas"?
Non, PB a de la ressource, et il y a le choix :D

3 manières de faire dans le cas d'API non déclarées :

1) Les API sont des fonctions d'une dll, il faut utiliser les fonctions librairies disponibles

Code : Tout sélectionner

CallCFunction
CallCFunctionFast
CallFunction
CallFunctionFast
CloseLibrary
CountLibraryFunctions
ExamineLibraryFunctions
GetFunction
GetFunctionEntry
IsLibrary
LibraryFunctionAddress
LibraryFunctionName
LibraryID
NextLibraryFunction
OpenLibrary
Il faut commencer avec la fonction OpenLibrary()
Un exemple est fourni avec la doc PB, voir la page d'aide PureBasic - Library

Tu trouveras aussi des exemples sur les forums


2) Cette manière, je ne l'ai pas faite depuis 2 ans, j'espère qu'elle fonctionne encore (je pense que oui)
Il s'agit de créer le fichier Pbl nécessaire à PureBasic pour pouvoir utiliser les API comme une fonction de PB suivi du caractère _

Tu trouveras les outilis necessaires dans le dossier PureBasic :
\Library SDK\DLL Importer

ou il y a un fichier texte (en anglais) et l'outil DLL Importer.exe qui permet de créer tout ça

Je ne développe pas mais il me semble avoir expliqué un peu ça ici (lis tout et c'est en deuxième page je crois )

http://www.purebasic.fr/french/viewtopic.php?t=2561

3) utiliser les Import de PB, mais pour cela, tu dois trouver le fichier lib correspondant à la dll ou sont tes API

Par exemple, le fichier UxTheme.lib pour la dll UxTheme.DLL
Ces fichiers lib , soit tu les trouves sur internet soit tu télécharges la doc de Microsoft (Plateforme SDK), voir le lien ici dans la liste des liens utiles de notre forum ici http://www.purebasic.fr/french/viewtopic.php?t=1498

Puis tu utilises les imports

Les imports peuvent être utilisés avec les dll même non microsoft et celle suivant le protocole C doivent être déclarées avec ImportC

Il y a un outil sympa de ts-soft sur le forum anglais qui génère le code d'import avec toutes les fonctions de la dll, utilises-le, il va bien
c'est Lib2PBImport Version 1.2

Il est ici

http://www.purebasic.fr/english/viewtopic.php?t=25353

Une précision sur les imports, valable pour la 1ère manière aussi : Vérifies toujours par code la présence de la dll.
Avec les imports, si la dll est absente, tu auras un message d'erreur en fonctionnement car les fonctions sont testées ou la présence de la dll, je ne sais pas.



Par exemple, Gdi+ étant loin d'être sur toutes les bécanes, voilà mon code pour tester sa présence (je colle ça tout au début, en initialisation)
Je stocke le nombre de fonctions, c'est un moyen simple de connaître la version de Gdi+ (Gdi+1.0 --> 609 fonctions, Gdi+ 1.1 630 fonctions si je me souviens bien)

Code : Tout sélectionner

If OpenLibrary(0, "GDIPLUS.DLL")
    gdiplusVersion = CountLibraryFunctions(0)
    CloseLibrary(0)
Else
   MessageRequester("Erreur", "GdiPlus.dll est absent, installez d'abord Gdiplus" , 16)
   End
EndIf
Debug gdiplusVersion
A+
Denis
popstatic
Messages : 83
Inscription : lun. 20/sept./2004 18:21
Localisation : derriere toi fais gaffe!

Message par popstatic »

merci c'est gentil, en effet j'avais deja cherché ou se trouvais cette api dans les fichiers système, d'apres msdn elle est dans kernel32.dll et genre kernel32.lib

j'ai bien ouvert la dll, cherché et trouvé la fonction mais je n'ai aps réussi a la faire marcher... alors que les autres fonctions api utilisées dans le mm contexte fonctionnent (et reconnues par pb)
bref tout ca pour dire que ce code

Code : Tout sélectionner

OpenConsole()

    #FILE_ACTION_ADDED=1
    #FILE_ACTION_REMOVED=2
    #FILE_ACTION_MODIFIED=3
    #FILE_ACTION_RENAMED_OLD_NAME=4
    #FILE_ACTION_RENAMED_NEW_NAME=5

    Structure FILE_NOTIFY_INFORMATION
        NextEntryOffset.l
        Action.l
        FileNameLength.l
        *FileName.l
    EndStructure
    Global fni.FILE_NOTIFY_INFORMATION
    Global *ptrToFni.l = @fni
    Debug *ptrToFni
    
    If Not OpenLibrary(1, "Kernel32.dll")
        End
    Else
        Debug "Kernel32.dll ok"
        If GetFunction(1, "ReadDirectoryChangesW")
            Debug "ReadDirectoryChangesW ok"
        EndIf
    EndIf   
    
Procedure WatchDirectory(dir.s)

HndN.l= FindFirstChangeNotification_(dir,#False,#FILE_NOTIFY_CHANGE_FILE_NAME)
While #True
    Debug "Waiting For notification..."
    WaitStatus.l = WaitForSingleObject_(HndN,#INFINITE)
    Select WaitStatus
        Case #WAIT_OBJECT_0
            Debug "modification"
               CallFunction(1, "ReadDirectoryChangesW",HndN,*ptrToFni,SizeOf(fni),0,#FILE_NOTIFY_CHANGE_FILE_NAME)
               ; Debug ReadDirectoryChanges_(HndN,*ptrToFni,SizeOf(fni),#False,#FILE_NOTIFY_CHANGE_FILE_NAME)
               Debug fni\Action
                FindCloseChangeNotification_(HndN)
    
    
    EndSelect
Wend
EndProcedure



WatchDirectory("C:\Documents and Settings\popstatic\Mes documents\")


Input()

End
ne fonctionne pas (encore)...
mais je ne connaissais pas les fonctions d'import de lib et de dll, je vais tester ça, ça marchera peut etre mieux.
PS: les paramètre optionels des dll doivent ils être impérativement remplis si on l'utilise depuis purebasic? je veux dire, cette fonction a 2/3 paramètres optionels, et que je ne souhaite pas uiliser... est ce que je dois faire quelque chose en particulier?
Asus bien? asus tres bien!
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Message par nico »

Ton programme s'arrête à cette ligne:
WaitStatus.l = WaitForSingleObject_(HndN,#INFINITE)

Je ne vois pas comment tu peux déduire que ton api ne fonctionne pas!

Essaye ça:
WatchDirectory("\\?\C:\Documents and Settings\popstatic\Mes documents\")
popstatic
Messages : 83
Inscription : lun. 20/sept./2004 18:21
Localisation : derriere toi fais gaffe!

Message par popstatic »

merci c'est gentil, en effet j'avais deja cherché ou se trouvais cette api dans les fichiers système, d'apres msdn elle est dans kernel32.dll et genre kernel32.lib

j'ai bien ouvert la dll, cherché et trouvé la fonction mais je n'ai aps réussi a la faire marcher... alors que les autres fonctions api utilisées dans le mm contexte fonctionnent (et reconnues par pb)
bref tout ca pour dire que ce code

Code : Tout sélectionner

OpenConsole()

    #FILE_ACTION_ADDED=1
    #FILE_ACTION_REMOVED=2
    #FILE_ACTION_MODIFIED=3
    #FILE_ACTION_RENAMED_OLD_NAME=4
    #FILE_ACTION_RENAMED_NEW_NAME=5

    Structure FILE_NOTIFY_INFORMATION
        NextEntryOffset.l
        Action.l
        FileNameLength.l
        *FileName.l
    EndStructure
    Global fni.FILE_NOTIFY_INFORMATION
    Global *ptrToFni.l = @fni
    Debug *ptrToFni
    
    If Not OpenLibrary(1, "Kernel32.dll")
        End
    Else
        Debug "Kernel32.dll ok"
        If GetFunction(1, "ReadDirectoryChangesW")
            Debug "ReadDirectoryChangesW ok"
        EndIf
    EndIf   
    
Procedure WatchDirectory(dir.s)

HndN.l= FindFirstChangeNotification_(dir,#False,#FILE_NOTIFY_CHANGE_FILE_NAME)
While #True
    Debug "Waiting For notification..."
    WaitStatus.l = WaitForSingleObject_(HndN,#INFINITE)
    Select WaitStatus
        Case #WAIT_OBJECT_0
            Debug "modification"
               CallFunction(1, "ReadDirectoryChangesW",HndN,*ptrToFni,SizeOf(fni),0,#FILE_NOTIFY_CHANGE_FILE_NAME)
               ; Debug ReadDirectoryChanges_(HndN,*ptrToFni,SizeOf(fni),#False,#FILE_NOTIFY_CHANGE_FILE_NAME)
               Debug fni\Action
                FindCloseChangeNotification_(HndN)
    
    
    EndSelect
Wend
EndProcedure



WatchDirectory("C:\Documents and Settings\popstatic\Mes documents\")


Input()

End
ne fonctionne pas (encore)...
mais je ne connaissais pas les fonctions d'import de lib et de dll, je vais tester ça, ça marchera peut etre mieux.
PS: les paramètre optionels des dll doivent ils être impérativement remplis si on l'utilise depuis purebasic? je veux dire, cette fonction a 2/3 paramètres optionels, et que je ne souhaite pas uiliser... est ce que je dois faire quelque chose en particulier?
Asus bien? asus tres bien!
Répondre