Conversion d'un code en Delphi.
Re: Conversion d'un code en Delphi.
Fais un messagerequester sur SetShareData(2, Count) pour savoir quelle est la valeur renvoyée (doit être <> de 0)
Re: Conversion d'un code en Delphi.
La valeur est de "46989320" donc bien <> 0
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
Re: Conversion d'un code en Delphi.
Bonjour,
Je ne vois pas pourquoi cela ne fonctionne pas avec cette fonction vu que visiblement le reste fonctionne?
Cordialement,
GallyHC
Je ne vois pas pourquoi cela ne fonctionne pas avec cette fonction vu que visiblement le reste fonctionne?
Cordialement,
GallyHC
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
Re: Conversion d'un code en Delphi.
Voici, quelques pistes de réflexions.
procedure SetShareData (address,data: Longint);
var p:pointer;
ret:longint;
begin
p:=ShareData;
asm
push edi
mov edi,p
add edi,address
add edi,address
add edi,address
add edi,address
mov ret,edi
mov eax,data
mov ds:[edi],eax
pop edi
end;
end;
function GetShareData (Address:Longint): Longint; stdcall;
var p:pointer;
k:longint;
begin
p:= ShareData;
asm
push edi
mov edi,p
add edi,address
add edi,address
add edi,address
add edi,address
mov eax,ds:[edi]
mov k,eax
pop edi
end;
Result:=k;
end;
Sauf erreur, car ça fait longtemps que je n'ai pas programmé en Delphi:
Une procedure ne renvoie pas de donnée alors que function en renvoie une.
Longint est fixé à 32 bits que ce soit avec un OS 32b ou 64b.
Un pointeur est déclaré avec un accent circonflexe mais s'utilise sans.
.Pointer permet de déclarer un pointeur non typé.
Les convention d'appel (ordre dans lequel les variables sont passées) d'une procedure ou d'une fonction se font selon différentes directives : register, pascal, cdecl, stdcall et safecall
La directive cdecl est utile pour les DLLs écrites en C ou C++ alors que stdcall et safecall sont plutôt utilisées avec l'API Windows API.
stdcall pour que la DLL puisse être utilisée "plus facilement" avec n'importe quel langage.
Il ne faut donc pas utiliser de pointeur pour ShareData (à mon avis).
Voilà, à essayer.
Mesa.
procedure SetShareData (address,data: Longint);
var p:pointer;
ret:longint;
begin
p:=ShareData;
asm
push edi
mov edi,p
add edi,address
add edi,address
add edi,address
add edi,address
mov ret,edi
mov eax,data
mov ds:[edi],eax
pop edi
end;
end;
function GetShareData (Address:Longint): Longint; stdcall;
var p:pointer;
k:longint;
begin
p:= ShareData;
asm
push edi
mov edi,p
add edi,address
add edi,address
add edi,address
add edi,address
mov eax,ds:[edi]
mov k,eax
pop edi
end;
Result:=k;
end;
Sauf erreur, car ça fait longtemps que je n'ai pas programmé en Delphi:
Une procedure ne renvoie pas de donnée alors que function en renvoie une.
Longint est fixé à 32 bits que ce soit avec un OS 32b ou 64b.
Un pointeur est déclaré avec un accent circonflexe mais s'utilise sans.
.Pointer permet de déclarer un pointeur non typé.
Les convention d'appel (ordre dans lequel les variables sont passées) d'une procedure ou d'une fonction se font selon différentes directives : register, pascal, cdecl, stdcall et safecall
La directive cdecl est utile pour les DLLs écrites en C ou C++ alors que stdcall et safecall sont plutôt utilisées avec l'API Windows API.
stdcall pour que la DLL puisse être utilisée "plus facilement" avec n'importe quel langage.
;Problème ici car un pointeur en PureBasic, d'après la doc, n'a pas la même taille sur un OS 32b ou 64b alors que le code assembleur ci-dessous réclame un taille 32b = longint).// global DLL data
;ShareData: ^longint; // shared
Il ne faut donc pas utiliser de pointeur pour ShareData (à mon avis).
Code : Tout sélectionner
ShareData.l=0 ;32b, c'est ok
Code : Tout sélectionner
Procedure.l GetShareData (Address.l) ;(procedureC.l ?, à vérifier )
; .l = toujours 32bits
k.l=0
p.l= ShareData;
;push edi; sauvegarde edi
; Edi=p; mov edi,p
; Edi= edi + address;add edi,address
; Edi= edi + address; add edi,address
;Edi= edi + address;add edi,address
;Edi= edi + address;add edi,address
;ici edi = p=sharedata + 4*address
; transfert de la donné qui est à l'adresse contenue dans edi vers eax;mov eax,ds:[edi]
K=peekL(p); mov k,eax; puis tranfert dans k
; pop edi
end;
Returnprocedure k;
endprocedure
Code : Tout sélectionner
procedure SetShareData (address.l,data.l) ;(procedureC ?)
ret.l=0
p.l=ShareData;
; push edi
;mov edi,p
; add edi,address
;add edi,address
;add edi,address
;add edi,address
P=sharedata + 4*address
Ret=p ;mov ret,edi
; mov eax,data
pokeL(ret,data) ;mov ds:[edi],eax
;pop edi
EndProcedure
Code : Tout sélectionner
ProcedureDLL AttachProcess(Instance)
hMapFile = CreateFileMapping_($FFFFFFFF, #Null, #PAGE_READWRITE, 0, DataSize, VirtualFileName)
If hMapFile = 0
MessageRequester("Error", "Error creating memory mapped file", #PB_MessageRequester_Ok)
End
Else
;pas de pointeur
ShareData = MapViewOfFile_(hMapFile, #FILE_MAP_WRITE, 0, 0, DataSize)
If ShareData = 0
MessageRequester("Error", "Error creating memory mapped file", #PB_MessageRequester_Ok)
EndIf
EndIf
EndProcedure
Mesa.
Re: Conversion d'un code en Delphi.
J'ai modifié, ça devrait être bon, là.
Re: Conversion d'un code en Delphi.
Bonjour et merci a toi aussi Mesa
Bon la y a du mieu plus de plantage par contre le boitier ne repond pas au demande je recherche le probleme
Merci,
GallyHC
Bon la y a du mieu plus de plantage par contre le boitier ne repond pas au demande je recherche le probleme
Merci,
GallyHC
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)
Re: Conversion d'un code en Delphi.
J'ai changé la façon de lancer l'exe, c'est ptet ça...
Re: Conversion d'un code en Delphi.
Bonjour tous,
Pour commencer déjà un grand merci à Djes (un plus grand Merci) et Mesa pour votre aide.
Je ne savais pas pourquoi cela ne fonctionner pas et l’erreur été toute bête. Le fonction d’envois ne porte pas le même nom que la fonction de la Dll de base alors forcement cela ne pouvait pas fonctionne dans un appel a cette nouvelle lib
Au moins j’aurais appris à comprendre l’assembler, car j’ai cherche le pourquoi du comment et avec votre aide voila le code de la Dll qui fonctionne :
J'ai ajouter en fait une fontion pour etre sur qu'un module Velleman VM116 soit présent (aussi appelé 8062 juste a cause de son PID, je l'ai decouvert dans mes recherches).
En fait si je le met que maintenant c'est que j'ai decouvert mon erreur que maintenant, pares beaucoup de tests.
Cordialement,
GallyHC
Pour commencer déjà un grand merci à Djes (un plus grand Merci) et Mesa pour votre aide.
Je ne savais pas pourquoi cela ne fonctionner pas et l’erreur été toute bête. Le fonction d’envois ne porte pas le même nom que la fonction de la Dll de base alors forcement cela ne pouvait pas fonctionne dans un appel a cette nouvelle lib

Au moins j’aurais appris à comprendre l’assembler, car j’ai cherche le pourquoi du comment et avec votre aide voila le code de la Dll qui fonctionne :
J'ai ajouter en fait une fontion pour etre sur qu'un module Velleman VM116 soit présent (aussi appelé 8062 juste a cause de son PID, je l'ai decouvert dans mes recherches).
Code : Tout sélectionner
; +======================================================+
; | LIBRAIRIE DU CONTROLEUR VM116 DE VELLEMAN |
; +------------------------------------------------------+
; | COPYRIGHT(C)2007-2012, ALL RIGHT RESERVED KOAKDESIGN |
; +--------------+---------------------------------------+
; | Program type | PUREBASIC 4.60 |
; +--------------+---------------------------------------+
; | VER & REV | 0.0.1 RC0 |
; +--------------+---------------------------------------+
; | Program name | main.pb |
; +======================================================+
; +======================================================+
; | Original Version: 0.0.1 RC0 |
; +--------------+---------------------------------------+
; | Created by | GallyHomeCorp |
; | Graphix by | |
; +--------------+---------------------------------------+
; | Comments: | |
; +--------------+ |
; | |
; | |
; | |
; +======================================================+
; +======================================================+
; | Système d'Exploitation |
; +--------------+---------------------------------------+
; | Window | Oui |
; | Linux | Non |
; | MacOS | Non |
; +======================================================+
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; +--------------------------------------------------------------------------+
; | |
; +--------------------------------------------------------------------------+
;- INITIALISATION DES DIRECTIVES COMPILEUR.
DisableASM
EnableExplicit
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; +--------------------------------------------------------------------------+
; | |
; +--------------------------------------------------------------------------+
;- DECLARATION DES VARIABLES (VERSION).
;{ - GLOBAL VERSION
#Version = "0.0.1"
#SubVers = ""
#VerDate = "01/12/2011"
Global FullVer.s
Global FullName.s = "K8062DM Library"
Global FullInfo.s = "K8062DM Library for Vellaman VM116 in PureBasic"
Global FilePath.s
If #SubVers = #NULL$
FullVer = #Version
Else
FullVer = #Version + "-" + #SubVers
EndIf
;}
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; +--------------------------------------------------------------------------+
; | |
; +--------------------------------------------------------------------------+
;- DECLARATION DES PROCEDURES DE LA DLL.
Declare AttachProcess(Instance.i)
Declare DetachProcess(Instance.i)
Declare AttachThread(Instance.i)
Declare DetachThread(Instance.i)
Declare.s setCutLigneVendor(value.s)
Declare.s setCutLigneHID(value.s)
Declare.b GetFoundVM116_8062()
Declare.b StartDevice()
Declare.b StopDevice()
Declare.b SetChannelCount(count.l)
Declare.b SetData(channel.l, ldata.l)
Declare.l GetShareData(address.l)
Declare SetShareData(address.l, ldata.l)
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; +--------------------------------------------------------------------------+
; | |
; +--------------------------------------------------------------------------+
;- DECLARATION DES VARIABLES (GLOBALE).
Structure SP_DEVINFO_DATA
cbSize.l
ClassGuid.GUID
DevInst.l
Reserved.l
EndStructure
Global *ShareData.i
Global hMapFile.l
Global running.b = #False
Global DataSize.l = 2500
Global VirtualFileName.s = "ShareK8062Data"
#VELLEMAN_INITOK = $0
#VELLEMAN_NOTFOUND = -1
#VELLEMAN_ERROR = -2
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; +--------------------------------------------------------------------------+
; | |
; +--------------------------------------------------------------------------+
ProcedureDLL.s DllName()
; DONNE LE NOM DE LA LIBRAIRIE.
ProcedureReturn FullName
EndProcedure
ProcedureDLL.s DllInformation()
; DONNE LES INFORMATIONS DE LA LIBRAIRIE.
ProcedureReturn FullInfo
EndProcedure
ProcedureDLL.s DllVerion()
; DONNE LA VERSION DE LA LIBRAIRIE.
ProcedureReturn FullVer
EndProcedure
ProcedureDLL.s DllDate()
; DONNE LA DATE DE LA LIBRAIRIE.
ProcedureReturn #VerDate
EndProcedure
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; +--------------------------------------------------------------------------+
; | |
; +--------------------------------------------------------------------------+
Procedure.s setCutLigneVendor(value.s)
; ROUTINE DE DECOUPAGE DES REPERTOIRES.
Define i.l
Define j.l = 0
For i=0 To Len(value) - 1 Step 1
If Mid(value, i, 1) = "&"
j = i - 1
Break
EndIf
Next i
If j > 0
ProcedureReturn Mid(value, 1, j)
EndIf
EndProcedure
Procedure.b GetFoundVM116_8062()
; ROUTINE DE RECHERCHE DES CONTROLEURS 8062.
Define value.l
Define usbid.s
Define dwReqLen.l
Define strBuffer.s
Define RegDataType.l
Define bresu.b = #False
Define idlib.l = OpenLibrary(#PB_Any, "cfgmgr32.dll")
Define ielib.l = OpenLibrary(#PB_Any, "setupapi.dll")
CompilerIf #PB_Compiler_Unicode
Define devic.l = GetFunction(idlib, "CM_Get_Device_IDW")
Define devid.l = GetFunction(ielib, "SetupDiGetDeviceRegistryPropertyW")
CompilerElse
Define devic.l = GetFunction(idlib, "CM_Get_Device_IDA")
Define devid.l = GetFunction(ielib, "SetupDiGetDeviceRegistryPropertyA")
CompilerEndIf
Define hDeviceInfoSet.l = SetupDiGetClassDevs_(0, 0, 0, #DIGCF_PRESENT | #DIGCF_ALLCLASSES)
Define DeviceInfoData.SP_DEVINFO_DATA : DeviceInfoData\cbSize = SizeOf(DeviceInfoData)
If hDeviceInfoSet <> #INVALID_HANDLE_VALUE
While SetupDiEnumDeviceInfo_(hDeviceInfoSet, value, @DeviceInfoData)
usbid = Space(255)
CallFunctionFast(devic, DeviceInfoData\DevInst, @usbid, Len(usbid), 0)
If LCase(Left(usbid, 3)) = "usb" And FindString(LCase(usbid) ,"pid_8062")
strBuffer = setCutLigneVendor(Mid(usbid, 5, Len(usbid) - 6 ))
If CountString(strBuffer, "_") > 0
strBuffer = StringField(strBuffer, 2, "_")
If Val("$" + strBuffer) = $10CF
bresu = #True
EndIf
EndIf
EndIf
value + 1
Wend
EndIf
CloseLibrary(idlib)
CloseLibrary(ielib)
SetupDiDestroyDeviceInfoList_(hDeviceInfoSet)
ProcedureReturn bresu
EndProcedure
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; +--------------------------------------------------------------------------+
; | |
; +--------------------------------------------------------------------------+
ProcedureDLL AttachProcess(Instance.i)
; INITIALISATION DU MAPPAGE POUR LA LIBRAIRIE.
hMapFile = CreateFileMapping_($FFFFFFFF, #Null, #PAGE_READWRITE, 0, DataSize, VirtualFileName)
If hMapFile = 0
MessageRequester("Error", "Error creating memory mapped file", #PB_MessageRequester_Ok)
Else
*ShareData = MapViewOfFile_(hMapFile, #FILE_MAP_WRITE, 0, 0, DataSize)
If *ShareData = 0
MessageRequester("Error", "Error creating memory mapped file", #PB_MessageRequester_Ok)
EndIf
EndIf
EndProcedure
ProcedureDLL DetachProcess(Instance.i)
; DESINITIALISATION DU MAPPAGE POUR LA LIBRAIRIE.
UnmapViewOfFile_(*ShareData)
CloseHandle_(hMapFile)
EndProcedure
ProcedureDLL AttachThread(Instance.i)
;
EndProcedure
ProcedureDLL DetachThread(Instance.i)
;
EndProcedure
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; +--------------------------------------------------------------------------+
; | |
; +--------------------------------------------------------------------------+
Procedure.l GetShareData(address.l)
; ROUTINE DE LECTURE DES DONNEES.
ProcedureReturn PeekL(*ShareData + (address * SizeOf(address)))
EndProcedure
Procedure SetShareData(address.l, ldata.l)
; ROUTINE D'ENVOIS DES DONNEES.
PokeL(*ShareData + (address * SizeOf(address)), ldata)
EndProcedure
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; +--------------------------------------------------------------------------+
; | |
; +--------------------------------------------------------------------------+
ProcedureDLL.b StartDevice()
; DEMARAGE DU CONTRÔLEUR VM116 DE VELLEMAN.
Define h.l
If GetFoundVM116_8062() = #True
SetShareData(1, 222)
RunProgram("k8062e.exe", "", "", #PB_Program_Hide)
If GetShareData(1) = 222
ProcedureReturn #VELLEMAN_INITOK
EndIf
EndIf
ProcedureReturn #VELLEMAN_NOTFOUND
EndProcedure
ProcedureDLL.b StopDevice()
; ARRET DU CONTRÔLEUR VM116 DE VELLEMAN.
SetShareData(0, 333)
EndProcedure
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; +--------------------------------------------------------------------------+
; | |
; +--------------------------------------------------------------------------+
ProcedureDLL.b SetChannelCount(count.l)
; ROUTINE DU NOMBRE DE CHANNEL UTILISE.
If count > 512
count = 512
EndIf
If count > 0
SetShareData(2, count)
EndIf
EndProcedure
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; +--------------------------------------------------------------------------+
; | |
; +--------------------------------------------------------------------------+
ProcedureDLL.b SetData(channel.l, ldata.l)
; ROUTINE D'ENVOIS DES DONNEES VM116.
If channel > 0 And channel < 513
SetShareData(channel + 10, ldata)
EndIf
EndProcedure
Cordialement,
GallyHC
Configuration : Tower: Windows 10 (Processeur: i7 "x64") (Mémoire: 16Go) (GeForce GTX 760 - 2Go) - PureBasic 5.72 (x86 et x64)