Déclaration + procédure dll C++

Résolu
scortek Messages postés 61 Date d'inscription mardi 4 mai 2004 Statut Membre Dernière intervention 1 août 2007 - 23 févr. 2007 à 09:16
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 - 23 févr. 2007 à 17:04
J'ai une dll C++ avec les fonctions déclarées comme ceci :
Int EPGetDeviceID(HANDLE *PrnHandle, LPTSTR lpDeviceID
);

Args:

HANDLE       PrnHandle     [IN] Printer handle acquired with
EPOpenComm function

LPTSTR         lpDeviceID     [IN] Pointer to memory storing the DeviceID
information

                                               [OUT]
Acquired the DeviceID information

 

Returns SUCCESS (0) if successful.

Returns the following error codes in case of error

DEVICE_IO_ERROR (4) Error with low level communication

 

int EPWriteComm(HANDLE PrnHandle, LPCVOID pData, DWORD
dwDataLen);

// Write to printer port handle

 

Args:

HANDLE       PrnHandle     [IN] Printer handle acquired with OpenComm
function

LPCVOID      pData             [IN] Pointer to memory storing
datas to send

DWORD        dwDataLen    [IN] Length of storing buffer

 

Returns SUCCESS (0) if successful.

Returns the following error codes in case of error

ERROR_ON_WRITTING_PORT (5)                     A port writing error has occured

ERROR_ON_WRITTING_FUNCTION (6)            A writing error has occured

 

 

int EPReadComm(HANDLE PrnHandle, LPVOID pData, DWORD
*dwDataLen);

// Read from printer port handle

Args:

HANDLE       PrnHandle     [IN] Printer handle acquired with OpenComm
function

LPVOID         pData             [IN] Pointer to memory which will
store received datas

                                               [OUT]
Acquired datas

DWORD        *dwDataLen  [IN] Pointer to length of storing buffer

                                               [OUT]
Length of acquired datas

 

Returns SUCCESS (0) if successful.

Returns the following error codes in case of error

ERROR_ON_READING_FUNCTION (7)A read error has occured

LPCVOID et LPVOID, vous connaissez ?
Comment déclarer ceci dans un module et l'utiliser dans le Form ?
Merci bien de votre aide.

16 réponses

cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
23 févr. 2007 à 12:25
Private Type TDevID
    Mfg as string * 256
    Cmd as string * 256
    Mdl as string * 256
    Cls as string * 256
    Des as string * 256
End Type

Dim DeviceID as TDevType

Mfg, cmd, ... sont les membres de ta structure

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
3
scortek Messages postés 61 Date d'inscription mardi 4 mai 2004 Statut Membre Dernière intervention 1 août 2007
23 févr. 2007 à 16:22
Les exports semblant faits en pur style C, je pense que tu peus réduire les déclarations:
Public Declare Function WriteComm Lib "EPComDll.dll" Alias "[mailto:_EPWriteComm@12 _EPWriteComm@12]" (ByVal handle As Long, ByVal LPCData As String, ByVal dwDataLen As Long) As Long

=> Non, je ne peux, le source dll que je n'ai point à été fait en VC++ 6

Casy, apparement, je ne peux tout avoir :
   Mfg as string * 256
    Cmd as string * 256
    Mdl as string * 256
    Cls as string * 256
    Des as string * 256

J'ai fait : GetID = GetDeviceID(hprinter, ID)
                 Text1.Text = ID.Mfg
                 Text2.Text = ID.Cmd
             .....
mais je n'ai que Text1.Text qui affiche la chaine et tout d'un coup, séparer par des ;  -> MFG:xxxxxxx;CMD:xxxxxxxxx;.......
Bizarre !?
Par contre pour une autre fonction appelant une structure similaire, j'ai le détail !?

Sinon, pour :
Public Declare Function WriteComm Lib "EPComDll.dll" Alias
"_EPWriteComm@12" (ByVal handle As Long, ByVal LPCData As String, ByVal
dwDataLen As Long) As Long

Public Declare Function ReadComm Lib
"EPComDll.dll" Alias "_EPReadComm@12" (ByVal handle As Long, ByVal
LPData As String, ByRef dwDataLen As Long) As Long

C'est OK, mais As Integer à la fin suffit et As any à la place de As String marche aussi !
3
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
23 févr. 2007 à 10:51
LPVOID : adresse mémoire
LPCVOID : idem, le C en plus indique qu'on ne fera QUE LIRE ce qui est à cette adresse.

ciao...
BruNews, MVP VC++
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
23 févr. 2007 à 10:53
LP pour Long Pointeur et Void pour type indefinie. Cela signifie que tu passe un pointeur long (adresse absolu) sur une variable de type non définie
Cela veut dire que tu doit passer à ta fonction, l'adresse mémoire de ta variable.

Alors comme ici tes variables seront des chaines de caractères, les choses se compliquent un peu. Une chaine de caractère passée à une fonction est déjà une adresse mémoire. MAis suivant comment est déclaré en C la variable de réception, il faut passer la chaine soit par valeur (ByVal) soit par référence (ByRef). Il faut donc que tu fasse l'essai avec les 2 cas.

Par contre, il faut que ta chaine existe en mémoire avant l'appel de la fonction. Une simple déclaration ne suffit pas, il faut remplir la chaine pour qu'elle soit créer en mémoire. En général on fait chaine = String(255,chr(0)) juste avant l'appel. Ca crée une chaine de 255 caractères.

Je suis pas sur d'avoir été très clair dans mes explications.

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
23 févr. 2007 à 11:13
On ne passe jamais une String VB par référence car ce serait l'adresse du BSTR et non la chaine (qui est un champ du BSTR). Il faudrait pour cela que la DLL ait été écrite spécialement pour VB.

ciao...
BruNews, MVP VC++
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
23 févr. 2007 à 11:22
Si si, ça m'est arrivé BruNews, sur une Dll écrite pour du C que j'ai dû utiliser en VB, pour une fonction où c'était un pointeur sur une variable qui était attendu. Cette variable étant elle-même un pointeur sur la zone mémoire de la chaine de caractère. La déclaration était celle-ci : (LPSTR *chaine)

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
23 févr. 2007 à 11:24
oups j'ai oublier la moitié de la phrase.
La déclaration était un (LPquelquechose chaine), et en fouillant dans les .h, j'ai réussi à trouvé qu'il correspondait à (LPSTR *chaine)

Déclaration perverse s'il peut en etre

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
23 févr. 2007 à 11:31
LPSTR *chaine
demande l'adresse d'un TABLEAU de chaine mais pas d'une chaine.

ciao...
BruNews, MVP VC++
0
scortek Messages postés 61 Date d'inscription mardi 4 mai 2004 Statut Membre Dernière intervention 1 août 2007
23 févr. 2007 à 11:55
Faire chaine = String(255,chr(0)) ou Dim chaine * 255 au début, c'est la même chose non ?

Sinon voici comment j'ai déclaré dans un module :
Public Declare Function WriteComm Lib "EPComDll.dll" Alias "_EPWriteComm@12" (ByVal handle As Long, ByRef LPCData As Any, ByVal dwDataLen As Long) As Integer

Public Declare Function ReadComm Lib "EPComDll.dll" Alias "_EPReadComm@12" (ByVal handle As Long, ByRef LPData As Any, ByRef dwDataLen As Long) As Integer

Public Declare Function GetDeviceID Lib "EPComDll.dll" Alias "_EPGetDeviceID@8" (ByVal handle As Long, ByRef DeviceID As String) As Integer

(J'avais oublier de vous préciser GetPrnHandle dont je suis sûr)
Public Declare Function GetPrnHandle Lib "EPComDll.dll" Alias "_EPGetEPLPrnHandle@8" (ByVal port As Integer, ByRef handle As Long) As Integer

Ce que j'ai mis en rouge, c'est ce dont je ne suis certain à 100%...

Et dans le Form :
Dim hPrinter As Long

Function SetHandle() As Boolean
    SetHandle = GetPrnHandle(USBPort, hPrinter)
End Function
'Ce qui est au-dessus ne changera plus

Dime ID * 255
Dim GetID As Integer
If (ID = 0) Then
        GetID = GetDeviceID(hPrinter, ID)   'ici ça plante sans me donner d'erreur et ça ferme de suite VB Studio, je sais pas pourquoi ?
        Text14.Text = ID
Else:
        MsgBox "Error with low level communication" & vbCrLf & Err.Description
End If

Dim Data As String
Dim Send As Integer
Dim DataLen As Long

Dim Buffer As String * 30
Dim Receive As Integer
Dim nb As Long

Data$ = Chr(64) & Chr(69) & Chr(74) & Chr(76) & Chr(32) & Chr(73) & _
               Chr(81) & Chr(32) & Chr(85) & Chr(83) & Chr(66) & Chr(73) & Chr(68) & vbCrLf
               'c'est une commande que j'envoi à l'imprimante

DataLen = Len(Data)

For i = 1 To 100   'tempo au-hasard pour attendre la réception

    If Send = 0 Then
            Send = WriteComm(hPrinter, Data, DataLen)
    ElseIf (Send = 5) Then
            MsgBox "A port writting error has occured" & vbCrLf & Err.Description
    ElseIf (Send = 6) Then
            MsgBox "A writting error has occured" & vbCrLf & Err.Description
    End If

    Receive = ReadComm(hPrinter, Buffer, nb)   'il y a rien dans le buffer ?
    nb = Len(Buffer)
    Buffer = Left(hPrinter, Buffer, nb) 'Troncage du buffer sur le nombre de caractères   effectivement lus mais ça me met comme erreur

Next i
  
    Text1.Text = Data & Lineoftext & vbCrLf
    Text1.Enabled = True
   
    Text2.Text = Buffer & Lineoftext & vbCrLf
    Text2.Enabled = True
  

CloseComm (hPrinter)  'ferme le port USB ou LPT

End Sub

Voilou, merci encore pour votre aide précieuse
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
23 févr. 2007 à 12:01
... Alias "[mailto:_EPGetDeviceID@8 _EPGetDeviceID@8]" (ByVal handle As Long, ByRef DeviceID As String)

j'ai expliqué plus haut pourquoi ByRef sur String VB ne peut pas aller.

ciao...
BruNews, MVP VC++
0
scortek Messages postés 61 Date d'inscription mardi 4 mai 2004 Statut Membre Dernière intervention 1 août 2007
23 févr. 2007 à 12:02
Buffer = Left(hPrinter, Buffer, nb) 
'Troncage du buffer sur le nombre de caractères   effectivement lus mais ça me met comme erreur








Désolé j'ai pas fini ma phrase :



ça me met comme erreur "Nombre d'arguments incorrect ou affectation de propriété incorrecte" (mais comm il ya rien dans le buffer, c'est peut-être normal ?
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
23 févr. 2007 à 12:14
hPrinter doit etre le handle que tu as lu avec la fonction EPOpenComm, déjà il faut commencer par ça.

Ensuite regarde dans ta doc, mais pour moi DeviceID doit etre certainement une structure que tu dois passer à la fonction pour qu'elle la remplisse.

Pour les déclarations j'aurais plutot mis ça :

Public Declare Function WriteComm Lib "EPComDll.dll" Alias "_EPWriteComm@12" (ByVal handle As Long, ByVal LPCData As String, ByVal dwDataLen As Long) As Long

Public Declare Function ReadComm Lib "EPComDll.dll" Alias "_EPReadComm@12" (ByVal handle As Long, ByVal LPData As String, ByRef dwDataLen As Long) As Long

Public Declare Function GetDeviceID Lib "EPComDll.dll" Alias "_EPGetDeviceID@8" (ByRef handle As Long, ByVal DeviceID As TypeDeLaStructure) As Long

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
0
scortek Messages postés 61 Date d'inscription mardi 4 mai 2004 Statut Membre Dernière intervention 1 août 2007
23 févr. 2007 à 12:16
J'ai essayé avec ByVal aussi mais ça ne passe pas, ça me met "Erreur d'exécution type 13, Type incompatible".
Si ça ne marche peut-être pas, c'est qu'il faudra peut-être faire un Public Type.
J'ai trouvé ça dans le source C :
#define MAX_DEVICE_NAME    256

typedef struct _DEVICEID{
    char MFG[MAX_DEVICE_NAME];
    char CMD[MAX_DEVICE_NAME];
    char MDL[MAX_DEVICE_NAME];
    char CLS[MAX_DEVICE_NAME];
    char DES[MAX_DEVICE_NAME];
}DEVICEID, *LPDEVICEID;

Traduction en Visual Basic ?? Vous connaisser MFG, CMD... ?
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
23 févr. 2007 à 12:28
Les exports semblant faits en pur style C, je pense que tu peus réduire les déclarations:
Public Declare Function WriteComm Lib "EPComDll.dll" Alias "[mailto:_EPWriteComm@12 _EPWriteComm@12]" (ByVal handle As Long, ByVal LPCData As String, ByVal dwDataLen As Long) As Long

en:
Public Declare Function EPWriteComm Lib "EPComDll.dll" (ByVal handle As Long, ByVal LPCData As String, ByVal dwDataLen As Long) As Long
VB devrait trouver les fonctions sans problème.

ciao...
BruNews, MVP VC++
0
BruNews Messages postés 21040 Date d'inscription jeudi 23 janvier 2003 Statut Modérateur Dernière intervention 21 août 2019
23 févr. 2007 à 16:38
"fait en VC++ 6" ne veut strictement rien dire, VC++ est un IDE et non un langage, on y écrit ASM, C ou C++.
Les noms de fonction exportées sont en pur export C stdcall (c'est une info, pas une question...), en C++ se reconnaitrait illico à la déco du nom et serait inutilisable par quelque autre langage.

ciao...
BruNews, MVP VC++
0
cs_casy Messages postés 7741 Date d'inscription mercredi 1 septembre 2004 Statut Membre Dernière intervention 24 septembre 2014 40
23 févr. 2007 à 17:04
"...C'est OK, mais As Integer à la fin suffit..."

NON, un int en C correspond à un long en VB, il te faut donc mettre le bon type correspondant sinon tu prend le risque d'avoir des appels instables sources de plantages.

Pour DeviceID, ok, il semblerait que ce soit bien une chaine de carctère dans ce cas là et non pas une structure. Farfelue ta dll.

Tu dis que tu as une autre fonction avec DeviceID sous forme de structure là, vérifie bien que le paramètre en C est bien de type
LPTSTR lpDeviceID

si c'est le cas je comprend plus rien, le parametre ne peux pas etre à la fois structure et chaine de caractère

---- Sevyc64  (alias Casy) ----<hr size="2" width="100%" /># LE PARTAGE EST NOTRE FORCE #
0
Rejoignez-nous