IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

API, COM et SDKs Delphi Discussion :

Communiquer avec une DLL externe


Sujet :

API, COM et SDKs Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 68
    Points : 45
    Points
    45
    Par défaut Communiquer avec une DLL externe
    [D2007 / WIN32]


    Bonjour,

    J'aurais besoin de vos avis concernant un petit projet, je vais faire le plus court possible

    J'ai créé une application WIN32 qui ouvre un processus (un jeu vidéo) et qui va y lire des données pour les afficher dans mon interface situé sur un autre écran en dualview (télémétrie simple en temps réel). Tout ça fonctionne très bien.

    J'ai créé ensuite un hook sur DirectX, c'est à dire D3D9.DLL que je place dans le répertoire du jeu, ce dernier la charge, ce qui me permet d'ajouter du graphisme dans l'image DX du jeu (pour l'instant une simple image plaquée et du texte statique [pour tester le hook, ça marche impec]).

    Mon objectif aujourd'hui est de communiquer avec cette DLL pour pouvoir afficher dans le jeu des données choisi par l'utilisateur (config.ini), le souci c'est que je ne sais pas comment faire et ni même si c'est possible

    Si j'avais été amené à afficher toutes les données directement dans le jeu le problème ne se poserait pas puisque j'aurais intégré la partie "scanner" dans la D3D9.DLL , on aurait plus eu besoin du dualview...
    Mais comme je ne veux pas aller jusque là, je suis contraint d'utiliser l'.exe pour scanner et afficher une partie des données, et d'en envoyer certaines à un rythme assez rapide à la DLL qui, elle, se contente d'afficher (il n'est pas question de scanner le jeu à nouveau par la DLL :/ )

    Comment voyez-vous la chose ?
    est-ce que je peux envoyer un flux régulier d'octets à la DLL ? (un peu comme je le ferais en client/server quoi...)

    Je ne sais pas du tout comment procéder :/ (messages ? o_O )
    Merci d'avance pour votre aide.

    Alekhine.

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 595
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 595
    Points : 25 277
    Points
    25 277
    Par défaut
    cette autre réponse pourrait te mettre sur différentes pistes dont le Serveur\Client TCP\IP

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 68
    Points : 45
    Points
    45
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    cette autre réponse pourrait te mettre sur différentes pistes dont le Serveur\Client TCP\IP

    Merci Shai,

    J'avais pensé au TCP/IP mais ça me semblait un peu fou lol

    Du coup ça tombe bien puisque j'ai déjà le serveur, la DLL sera un client comme un autre

    Alek.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 68
    Points : 45
    Points
    45
    Par défaut
    Bon finalement c'est pas mal le TCP/IP, mais y-a quand même des inconvénients dûs au hook :s

    1) Quand y-a un problème de socket, genre err 10053 qui arrive parfois (ou jamais..) sans que je comprenne pourquoi, le jeu crash :o
    En couse officielle de ligue, si j'envois le pilote sur le bureau je m'attends à des félicitations nourries par email (arff)

    2) Le hook c'est un peu du bricolage, pas de "OnClose", bonjour pour sortir propre :/ notamment pour socket.close; , du coup le serveur aime pas trop le voyage.

    Je vais pousser un peu plus loin, mais à mon avis le plus fiable est de tout mettre dans la DLL, y compris le scanner, sans communication extérieur.
    Dommage.


    PS: Si quelqu'un vend d'occas un bouquin pour apprendre DirectX 9 qu'il me contact en MP

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 68
    Points : 45
    Points
    45
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    cette autre réponse pourrait te mettre sur différentes pistes dont le Serveur\Client TCP\IP
    C'est re-moi, fatigué (lol)

    Bon j'ai exploté la piste TCP, mais y-a un truc que je ne sais pas gérer ou qui n'est peut être pas gérable dans le cadre d'un hook : les messages...

    En fait je ne suis pas dans "mon" application puisque je hook le rafraichissement de l'écran (directx) pour le surchager.

    Comme c'est le seul endroit (le refresh du jeu) ou j'ai la main en dehors de l'initialisation proprement dite de ma dll, j'en ai profité pour créer un simple petit compteur de frame et je fais un "Application.ProcessMessages" toutes les 15 frames env.

    C'est comme ça que mon socket peut fonctionner, sinon il est freeze dans son coin et la connexion meurt d'elle-même.

    Le souci c'est que si l'application directx n'a plus le focus, par exemple si je fais alt-tab pour aller quelques instants sur le bureau, le jeu est en pause et il n'y a plus de rafraichissement de l'écran évidemment, ce qui veut dire aussi qu'il n'y a plus mon Application.ProcessMessages :/ le jeu plante parce que le socket meurt en timeout...

    J'ai essayé de mettre l'Application.ProcessMessage dans un timer mais ça ne sert à rien :o (pourquoi ? o_O )

    Y-a-t'il un autre moyen pour que mon code perso dans ce hook continue à recevoir les messages ?
    Si je n'arrive pas à ça je devrais définitivement arrêter de vouloir communiquer en dehors du jeu/hook, donc fini le Client/Server

  6. #6
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 173
    Points
    4 173
    Par défaut
    J'ai essayé de mettre l'Application.ProcessMessage dans un timer mais ça ne sert à rien :o (pourquoi ? o_O )
    Tout simplement parce que le composant Timer va en fait poster un message à interval de temps régulier. L'événement OnTimer ne déclenche que lorsque le message est traité

    Pour ce que tu veux faire de toute façon, je ne pense pas qu'un dialogue TCP/IP soit une bonne idée.
    A ta place, j'inverserais le fonctionnement : Ton appli calcule ses données, mais au lieu de les envoyer à la DLL, elle les garde à disposition dans un coin de la mémoire.

    Lorsque le hook a besoin des infos, il va lire la dernière version des infos de l'appli pour les afficher...
    Il suffirait pour celà de travailler en mémoire partagée :
    http://msdn.microsoft.com/en-us/library/ms810613.aspx

  7. #7
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    Tu peux aussi passer par un WM_COPYDATA vers une fenêtre dédiée (ou pas) de ta DLL

    FindWindow() pour trouver la fenetre et le tour est joué

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 68
    Points : 45
    Points
    45
    Par défaut
    Citation Envoyé par Franck SORIANO Voir le message
    Tout simplement parce que le composant Timer va en fait poster un message à interval de temps régulier. L'événement OnTimer ne déclenche que lorsque le message est traité

    Pour ce que tu veux faire de toute façon, je ne pense pas qu'un dialogue TCP/IP soit une bonne idée.
    A ta place, j'inverserais le fonctionnement : Ton appli calcule ses données, mais au lieu de les envoyer à la DLL, elle les garde à disposition dans un coin de la mémoire.

    Lorsque le hook a besoin des infos, il va lire la dernière version des infos de l'appli pour les afficher...
    Il suffirait pour celà de travailler en mémoire partagée :
    http://msdn.microsoft.com/en-us/library/ms810613.aspx
    Bonjour,

    Ok pour le timer, logique :/

    L'autre technique je ne la connait pas, mais elle est très interressante

    Mais si j'ai créé ma dll en "client" c'est d'une part parce que le serveur existe déjà, et d'autre part parce que ce serveur accepte 2 connexions dont une distante (dans ce cas: la dll sur le même PC, et le client standard de type TForm sur un laptop en réseau local ou un PC sur internet). Ca parait un peu énorme mais les joueurs de simu organisent des courses de 24h avec relais, tout cela est pris très au sérieux et du coup les team managers prennent des infos à distance pour conseiller le pilote (!)...

    C'est pour ça que je voulais conserver le TPC/IP; Si je dois l'abandonner j'ai autant intégrer le scanner dans la DLL, elle deviendrait autonome.
    Ce qui est moins joyeux c'est qu'il vont surement démarrer quand même le serveur pour leur team manager et du coup le jeu va être scanné deux fois je voudrais éviter ça.

    Je vais encore creuser...

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 68
    Points : 45
    Points
    45
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    Tu peux aussi passer par un WM_COPYDATA vers une fenêtre dédiée (ou pas) de ta DLL

    FindWindow() pour trouver la fenetre et le tour est joué
    Bonjour,

    Effectivement http://msdn.microsoft.com/en-us/libr...11(VS.85).aspx

    Par contre je ne comprends pas "qui" doit envoyer "à qui" ?
    Ma dll n'est pas une fenêtre, elle n'est même pas un process windows puisque le jeu la charge en croyant charger la dll microsoft (D3D9.DLL) ^^
    C'est moi qui charge la "vrai" dans \system32

    Du coup je ne vois pas comment identifier mon code perso pour le WM_COPYDATA ?

    En fait je n'ai pas de "boucle d'attente" (Application.run) dans mon code :/
    La seule "boucle" que j'ai c'est le rafraichissement de l'écran directx du jeu [qui n'est pas mon application], jusqu'au moment ou le jeu n'a plus le focus

    Alek.


    (exemple d'ajout dans l'image en bas à gauche)
    Images attachées Images attachées  

  10. #10
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    alors, si, je t'assure que ta DLL est un process Windows ^^

    je me suis déjà amusé aussi à remplacer la DLL DirectX par une version perso

    je ne connais pas D3D9.DLL mais si elle fonctionne comme les autres, elle publie une fonction qui retourne une interface qui sert de point d'entrée. Toi tu crées ta propre implémentation de l'interface qui s'appuie sur l'originale et qui ajoute le moment venu ce qui t'intéresse.

    Dans ce cas tu n'as effectivement pas de gestion de messages...Sauf à lancer un thread qui créera une fenêtre et bouclera sur la gestion de message par exemple.

    Tu peux aussi exploiter un fichier mémoire, toujours dans un thread.

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    68
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 68
    Points : 45
    Points
    45
    Par défaut
    Citation Envoyé par Paul TOTH Voir le message
    alors, si, je t'assure que ta DLL est un process Windows ^^

    je me suis déjà amusé aussi à remplacer la DLL DirectX par une version perso

    je ne connais pas D3D9.DLL mais si elle fonctionne comme les autres, elle publie une fonction qui retourne une interface qui sert de point d'entrée. Toi tu crées ta propre implémentation de l'interface qui s'appuie sur l'originale et qui ajoute le moment venu ce qui t'intéresse.

    Dans ce cas tu n'as effectivement pas de gestion de messages...Sauf à lancer un thread qui créera une fenêtre et bouclera sur la gestion de message par exemple.

    Tu peux aussi exploiter un fichier mémoire, toujours dans un thread.

    Re,

    héhé oui c'est un process windows :p mais je voulais dire que c'est pas comme une application windows qu'on trouve dans la liste des process.. là c'est facile de pointer dessus (mon serveur le fait (OpenProcess, ReadProcess..., ...)

    Je viens de remarqué à l'instant que je n'ai aucun problème quand je lance le jeu en mode fenétré :o ; En ce moment même il est minimisé et continue à communiquer avec le serveur.
    C'est en mode plein écran du jeu que les messages ne passent plus dès l'instant ou je fais alt-tab pour retourner sur le bureau (bizarre ça non ? )

    Du coup je me demande si je ne vais pas créer une TForm invisible et y glisser mon TClientSocket dessus pour voir comment ça se passe... :p

    Bon je vais encore creuser, je ne suis pas pressé, et au pire si vraiment c'est trop problématique j'intègrerais le scanner dans la DLL, ça sera ma porte de sortie

    Alek.

Discussions similaires

  1. Communiquer avec une application externe en Java
    Par Aude35 dans le forum Général Java
    Réponses: 1
    Dernier message: 25/07/2013, 16h41
  2. [Débutant] Faire communiquer PHP avec une DLL C#
    Par nicko_73 dans le forum C#
    Réponses: 1
    Dernier message: 29/06/2012, 09h48
  3. communiquer avec une DLL (COM interop)
    Par aA189 dans le forum EDI/Outils
    Réponses: 0
    Dernier message: 23/04/2010, 20h24
  4. Comment communiquer avec une dll, source à l'appui
    Par alpha_one_x86 dans le forum C++
    Réponses: 3
    Dernier message: 06/11/2008, 19h17
  5. Communiquer avec une DLL depuis un driver .SYS
    Par barthelv dans le forum Windows
    Réponses: 17
    Dernier message: 03/04/2006, 10h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo