Déclaration en C++ d'une DLL à traduire en VB

jaja - 19 nov. 2001 à 23:24
VBsat62fr Messages postés 56 Date d'inscription lundi 5 mai 2003 Statut Membre Dernière intervention 23 août 2017 - 16 août 2004 à 16:01
Bonjour à tous,
Mon pb: J'ai une DLL, la déclaration et le fonctionnement pour l'utiliser en C++ et je voudrais traduire tout ça en VB.
Voici le code source:

This dll (voxcnvrt.dll) performs sound format and sample rate conversions, as well as filtering by low-pass, high-pass, DTMF or clarity filters, volume equalization, sound centering, leader/trailer adjustments and sound enhancement.
The dll needs one input file name, one output file name and all conversion parameters necessary to process the input sound file. The result of the conversion is stored in the output file. It is a file to file conversion routine. The parameters needed to do the conversion are passed from the calling application to the dll by means of a globally allocated structure which contains all necessary information for the conversion. The C code command to initiate a conversion in the calling app is the following:

VoxFileConvert(lpFileConvert);

where VoxFileConvert is the name of the dll conversion procedure and lpFileConvert is a pointer to the structure conveying the parameters describing what to do during the conversion, on which file to act and in which file to store the result.

The FileConvert structure is defined as follows (see also the VCHeader.h file, which has to be included in your app):

typedef struct tFILECONVERT
{
long lStructSize;
BOOL bCallback;
HWND hCallbackWindow;
long CallbackID;
LPSTR szInputFile;
WORD wInputFormat;
DWORD dwInputRate;
WORD wInputChannels;
LPSTR szOutputFile;
WORD wOutputFormat;
DWORD dwOutputRate;
WORD wOutputChannels;
BOOL bFilter;
WORD FilterType;
DWORD LopassCutoff;
DWORD HipassCutoff;
BOOL bSilence;
float SilenceVal;
DWORD LeaderLength;
DWORD TrailerLength;
BOOL bNormalize;
float NormalizeVal;
BOOL bClarity;
short ClarityVal;
BOOL bCenter;
BOOL bOldWaveFormat;
BOOL bLogIt;
LPSTR szLogFile;
BOOL bErrorMessage;
LPSTR szErrorMessage;
WORD ReturnCode;
DWORD Reserved;
} FILECONVERT,*PFILECONVERT,far *LPFILECONVERT;

Je n'arrive pas à acceder à la DLL sans message d'erreur du genre "appel de la dll incorrecte !"

Merci d'avance.

4 réponses

Salut!...

Ce qui est rigolo [si j'ose le dire!], c'est que j'venais de lire justement 1 texte portant sur la traduction des APIs écrits en C++ en Visual Basic!... ;)

Donc, je fais 1 copie-collé du texte intégral ci-dessous en espérant que ça va t'aider!... :-p

Je le mettrais aussi dans les tutoriels...

Bonne lecture & bonne prog'!!!!!!!!!!

Gogogogogogogogogogooooooooooooooo

Convertir les déclarations Api du C++ vers Visual Basic

Note: toutes les exemples ci-dessous sont tirés du fichier CommCtrl.h, le fichier header des Windows Common Controls Api.

Constantes
Nous débutons cet apprentissage par les constantes, car c'est certainement le moyen le plus facile pour commencer.
Premier exemple :
#define ICC_COOL_CLASSES 0x00000400 // rebar (coolbar) control
La 1ère chose à noter est // rebar (coolbar) control. En C++, 2 slashs (//) sont utilisés comme simple ligne de commentaire, sachant que ce commentaire se terminera forcément en fin de ligne.
#define est utilisé pour créer des macros. Mais VB ne peut pas créer de macros, mais lorsque l'on convertit de C++ vers VB, on transcris ces lignes en constantes.
Dans ce cas #define deviendra Public Const si vous déclarez ces constantes dans un module VB.
Manifestement ICC_COOL_CLASSES est le nom de la constante.
Donc pour le moment, nous avons
Public Const ICC_COOL_CLASSES 0x00000400 ' rebar (coolbar) control
mais tout cela ne fonctionnera pas dans un projet VB. Nous avons convertis les commentaires ainsi que la déclaration #define. Une constante possède une valeur. Mais quel est cet étrange nombre ??
Tout simplement, il s'agit d'une valeur hexadécimale. En C++, toutes les valeurs hexa commencent avec le caractère "0x". Il suffit de d'adapter cette valeur à VB : &H00000200, ou depuis que les 0 d'en-têtes ne sont plus affichés en VB : &H200.
Maintenant la seule chose restant à faire est d'insérer le caractère "=" entre le nom et la valeur :
Public Const ICC_COOL_CLASSES = &H200 ' rebar (coolbar) control
Comme exercice, transcrivez les valeurs suivantes en VB :
#define ICC_UPDOWN_CLASS 0x00000010 // updown
#define ICC_PROGRESS_CLASS 0x00000020 // progress
#define ICC_HOTKEY_CLASS 0x00000040 // hotkey
#define ICC_ANIMATE_CLASS 0x00000080 // animate
#define ICC_WIN95_CLASSES 0x000000FF
#define ICC_DATE_CLASSES 0x00000100 // month picker, date picker, time picker, updown
#define ICC_USEREX_CLASSES 0x00000200 // comboex
Regardez les constantes suivantes :
#define ODT_TAB 101
#define ODT_LISTVIEW 102
Tout simplement, ces valeurs ne sont pas hexa, de cette manière on peut directement les convertir en :
Public Const ODT_TAB = 101
Public Const ODT_LISTVIEW = 102
Voici encore une autre variation de déclarations de constantes en C++ :
#define TTN_FIRST (0U-520U) // tooltips
#define TTN_LAST (0U-549U)
Ici les valeurs se terminent par "U", ce qui veut dire que la constante est du type "unsigned long", un type de donnée non supporté par VB. Cela veut-il dire qu'on ne peut pas utiliser ces constantes ? Pas du tout! Une donnée du type unsigned long ou signed long (en VB Long) sont stockées internement de la même façon, et la seule différence est la façon dont ils sont affichées. Dans ce cas, tout ce qu'on doit faire, est d'enlever le "U" de la déclaration et d'insérer le caractère "=" :
Public Const TTN_FIRST = (0 - 520) ' tooltips
Public Const TTN_LAST = (0 - 549)
De temps en temps, vous rencontrerez aussi des valeurs se terminant par "L". Cela veut dire que la constante est du type Long, et vous pouvez aussi enlever ce caractère, comme le U ci-dessus.
Et comment fait-on avec ces constantes ?
#define CDDS_ITEMPREERASE (CDDS_ITEM | CDDS_PREERASE)
#define CDDS_ITEMPOSTERASE (CDDS_ITEM | CDDS_POSTERASE)
De même, cela est aussi une convertion facile. Le caractère "|" est un opérateur ou bitwise en C++, comme l'opérateur Or en Visual Basic. Remplacez | par Or :
Public Const CDDS_ITEMPREERASE = (CDDS_ITEM Or CDDS_PREERASE)
Public Const CDDS_ITEMPOSTERASE = (CDDS_ITEM Or CDDS_POSTERASE)
Structures
Connus sous "Types" ou "Types défini par l'utilisateur" en VB, déclaré en utilisant le mot clé Type. Maintenant il va falloir faire plus que d'insérer le signe "=" ou d'enlever certains caractères bizarres - il faudra convertir des types de données, et dans certains cas ce sera très vicieux.
Commençons avec un exemple simple :
typedef struct tagTBSAVEPARAMSA {
HKEY hkr;
LPCSTR pszSubKey;
LPCSTR pszValueName;
} TBSEVEPARAMSA, FAR* LPTBSAVEPARAMSA;
typedef struct tagTBSAVEPARAMSW {
HKEY hkr;
LPCSTR pszSubKey;
LPCSTR pszValueName;
} TBSEVEPARAMSW, FAR* LPTBSAVEPARAMSW;
Et cela est supposé être simple ? Le 1ère note a prendre est que nous avons 2 structures qui sont pratiquement idem, à part sur un point : la 1ère structure TBSAVEPARAMSA est utilisée pour compiler du code ANSI, tandis que la seconde est utilisée pour des programmes UNICODE. En fait toutes les structures utilisées pour ANSI se terminent par la lettre A dans leur nom, et les structures UNICODE se terminent par W. A part les noms, la seule différence est le type de chaîne utilisée - ANSI ou UNICODE. Visual Basic ne vous autorise pas à appeler la partie UNICODE de l'Api (bien que cela est possible si vous aimez vous compliquer la vie), donc vous n'avez pas besoin de la version UNICODE.
Commençons par la 1ère ligne :
typedef struct tagTBSAVEPARAMSW {
1ère chose, convertissons la partie typedef struct en Public Type. Maintenant, le nom de la structure est quelque part sur le reste de la ligne. Beaucoup de C++ structures commencent avec le mot "tag", mais VB n'a pas besoin de ce mot, on peut donc l'enlever. Vous pouvez aussi faire sauter le A en fin du nom, car vous n'avez pas à différencier les versions ANSI et UNICODE de la structure, de même que le caractère "{" que vous pouvez aussi enlever. Qu'avons nous pour le moment :
Public Type TBSAVEPARAM
Les 3 lignes suivantes sont les membres de la structure :
HKEY hkr;
LPCSTR pszSubKey;
LPCSTR pszValueName;
Au contraire de Visual Basic, en C++ le type de données est en 1er et le nom de la variable en second. Quel est l'équivalent en VB du type HKEY en C++ ? Une chose a toujours retenir lorsque vous convertissez est que la plupart des types de données en C++ commençant par H sont des handles vers quelque chose. Si vous avez utilsé les Api Win32, vous savez certainement ce qu'est un handle ; chaque objet Form (et beaucoup de contrôles) en VB possède une propriété hWnd, que l'on peut traduire par "handle to a Window". La propriété hWnd est du type Long en VB, et toutes les variables qui stockent des handles le sont. Donc la conversion correct pour cette variable est :
hkr As Long
Similairement, les types de données LPSTR et LPCSTR en C++ sont converties en chaînes (String). Ces types sont des pointeurs vers des chaînes, mais vous n'avez pas besoin de vous en préoccupez en VB, car lorsque vous envoyez une structure vers Api, VB convertira toutes les chaînes dans la structure en pointeur vers des chaînes ANSI. Donc, les 2 autres membres de la structure peuvent être converti en :
pszSubKey As String
pszValueName As String
Attaquons maintenant la dernière ligne :
} TBSEVEPARAMSA, FAR* LPTBSAVEPARAMSA;
Tout ce qui se trouve après "}" n'intéresse plus les développeurs VB et peut être enlever. Il suffit simplement de rajouter le familier End Type.
Voila à quoi ressemble tout cela en VB :
Public Type TBSAVEPARAMS
hkr As Long
pszSubKey As String
pszValueName As String
End Type
Voici un autre exemple, mais un peu plus grand cette fois :
typedef struct {
UINT cbSize;
DWORD dwMask;
int idCommand;
int iImage;
BYTE fsState;
BYTE fsStyle;
WORD cx;
DWORD_PTR lParam;
LPSTR pszText;
int cchText;
} TBBUTTONINFOA, *LPTBBUTTONINFOA;
Oops !! Le nom de la structure ne se trouve pas après typedef.
Vous devez vous rappelez que, en règle générale, lorsque le nom de la structure ne se trouve pas sur la 1ère ligne, il se trouve alors sur la dernière ligne. Vous voyez aussi que le nom se termine par A (ANSI).
Donc la dernière ligne spécifie le nom de la structure (ci-dessous en rouge) :
} TBBUTTONINFOA, *LPTBBUTTONINFOA;
Donc la 1ère ligne ressemblera en VB a ceci :
Public Type TBBUTTONINFO
Maintenant il faut convertir toutes les variables du type C++ en Visual Basic.
Pour cela, veuillez consulter la page sur la conversion du type de donnée.
En utilisant ces renseignements, vous pouvez convertir presque n'importe quelle structure C++ vers son équivalent en VB.
Donc voici la conversion de la structure étudiée :
Public Type TBBUTTONINFO
cbSize As Long
dwMask As Long
idCommand As Long
iImage As Long
fsState As Byte
fsStyle As Byte
cx As Long
lParam As Long
psztext As String
cchText As Long
End Type
Fonctions
Connaître de quelle manière convertir les déclarations de fonction en C++ est extrènement précieux, car il y a une très grande partie d'appel de fonction Api qui ne se trouve pas dans la visionneuse d'Api livréé avec VB.
Prenons notre 1 er exemple (exporté de CommCtl32.dll) :
WINCOMMCTRLAPI HWND WINAPI CreateStatusWindowA(LONG style,
LPCSTR lpszText,
HWND hwndParent,
UINT wID);

WINCOMMCTRLAPI HWND WINAPI CreateStatusWindowW(LONG style,
LPCWSTR lpszText,
HWND hwndParent,
UINT wID);
Cet appel crée un contrôle StatusBar - vous ne trouverez cette déclaration nul part dans la doc de VB ! Les types de données (déjà abordé dans la partie Structures et plus précisément sur cette page) que vous savez maintenant convertir, sont ici exactement pareil.
Encore une fois il y a 2 versions de la déclaration : une avec ANSI et l'autre en UNICODE. Vous vous souvenez qu'en VB nous utilisons la déclaration ANSI, donc enlevons l'UNICODE. :
WINCOMMCTRLAPI HWND WINAPI CreateStatusWindowA(LONG style,
LPCSTR lpszText,
HWND hwndParent,
UINT wID);
En 1er que veut dire WINCOMMCTRLAPI ? Il dit tout simplement au C++ compilateur que cette fonction peut-être exportée de ComCtl32.dll. Avec des fonctions d'autres DLL, le préfix sera différent, et tous n'ont pas toujours de sens. Parfois, vous n'avez qu'a jeter un oeil sur une fonction dans MSDN Online Library pour savoir de quelle DLL elle provient.
Ensuite vient le type de retour de la fonction : HWND. Vous savez maintenant que HWND est convertit en Long en VB, et comme le type de retour de la fonction est HWND vous pouvez être certain que cette fonction retournera le hWnd de la Statusbar crée, si la fonction aréussi biensûr.
Qu'avons nous pour le moment :
Public Declare Function CreateStatusWindowA Lib "comctl32.dll" _
(.......) As Long
Vous vous demandez sûrement comment les arguments de cette fonction peuvent être déclarés sur plusieurs lignes sans un caractère de continuation de ligne - la ligne est automatiquement continué jusqu'à ce que le compilateur arrive au caractère point-virgule ";".
En VB si vous voulez déclarer une fonction sur plusieurs lignes, vous devez utiliser le caractère de continuation de ligne, le caractère souligné "_".
Public Declare function CreateStatusWindowA Lib "Comctl32.dll" _
(ByVal style As Long, _
Byval lpszText As String, _
ByVal hwndParent As Long, _
ByVal wID As Long) As Long
Voici encore une autre fonction à étudier :
WINCOMMCTRLAPI void WINAPI MenuHelp(UINT uMsg,
WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
HINSTANCE hInst, HWND hwndStatus, UINT lpwIDs);
et
WINCOMMCTRLAPI void WINAPI MenuHelp(UINT uMsg,
WPARAM wParam, LPARAM lParam, HMENU hMainMenu,
HINSTANCE hInst, HWND hwndStatus, UINT FAR *lpwIDs);
Les 2 déclarations sont identique uniquement pour le dernier paramètre. Le paramètre dans la seconde déclaration est :
UINT FAR *lpwIDs
Cette seconde déclaration est celle qui est correct, mais savez vous ce qui doit être changé dans la conversion VB lorsqu'un type de donnée est déclaré comme pointeur ("*" ou "FAR") ? Si vous ne l'avez jamais fait auparavant, surement que non. En VB, vous savez que les pointeurs sont une référence à une variable. Ok ?
La plupart des paramètres sont déclarés avec ByVal, mais lorsqu'un paramètre est un pointeur il faut déclarer le paramètre sans ByVal (en d'autre mot, c'est ByRef).
Mais, comme toujours il y a toujours une exception dans la règle. Cette exception intervient lorsque le pointeur (paramètre) est une chaîne (String). Un pointeur String doit toujours être déclaré ByVal, à moins qu'il soit défini comme un "pointeur vers un pointeur", ou lorsqu'on utilise 2 astérisques ** au lieu d'un seul *. dans le cas de 2 astérisques, la conversion doit être un paramètre ByRef.... As Long, et la valeur Long passée doit être égal à StrPtr(MyStringVar). StrPtr est une fonction VB non documentée qui retourne le pointeur au début d'un String.
Un autre point, est que menuhelp's retourne un type de donnée déclaré comme void. Ce qui veut dire que l'appel n'a pas de valeur de retour, en d'autre mot, ce n'est pas une fonction mais une Sub.

MenuHelp Sub doit être converti ainsi :

Public Declare Sub MenuHelp Lib "Comctl32.dll" _
(ByVal uMsg As Long, _
ByVal wParam As Long, _
ByVal lParam As Long, _
ByVal hMainMenu As Long, _
ByVal hInst As Long, _
ByVal hwndStatus As Long, _
lpwIDs As Long)

Equivalence des types de données C++ en VB

Type de donnée C++ Equivalent VB
short Integer
int Long
long Long
UINT Long
ULONG Long
WORD, DWORD Long
WPARAM, LPARAM Long
WMSG, UMSG Long
HRESULT Long
BOOL Long
COLORREF Long
HWND, HDC, HBRUSH, HKEY, etc... (windows handles) Long
LPSTR, LPCSTR String
LPWSTR, OLECHAR, BSTR String
LPTSTR String
VARIANT_BOOL Boolean
unsigned char Long
BYTE Byte
VARIANT Byte
tout type de donnée avec * ou ** à la fin Long
ATOM Integer
LPDWORD Long
LPINT, LPUINT Long
LPRECT Type défini par l'utilisateur (As type)
LPVOID Any
LPWORD Integer
LRESULT Long
NULL Any ou ByVal ... As Long

Bon j'espère que c'est assez lisible pour toi?... Car le tableau n'est pas clair, en fait, les caractères en majuscules concernent C++ et ceux en minusucles sont ds la conlonne VB, je pense que t'avais deviné... ;)

Sinon, va tjrs voir le zip dans les tutoriaux, c'est qd même + clair!... [;P]
0
Merci beaucoup pour la rapidité de cette réponse.
Longue vie @ ce forum ;)
0
-------------------------------
Réponse au message : De rien mon gars, y en a qui lisent ça ts les jrs, tu sais!!! ;)

Allez bonne prog'!!!!!!!!!! :-p

Gogogogogogogogooooooooooo

Ouais, longue vie au forum & à VBFRANCE.COM!!!!!!!!!!
-------------------------------

Merci beaucoup pour la rapidité de cette réponse.
Longue vie @ ce forum ;)
0
VBsat62fr Messages postés 56 Date d'inscription lundi 5 mai 2003 Statut Membre Dernière intervention 23 août 2017
16 août 2004 à 16:01
Bonjour,
Dans ce genre de log, éviter de mettre le message d 'origine avec...
Sinon ça donne ceci, bonne lecture...

VBSat

c'est quand les carrotes sont cuites que c'est la fin des haricots et bilatéralement!
0
Rejoignez-nous