DLL : interface IUnknown en C

Signaler
Messages postés
116
Date d'inscription
dimanche 26 septembre 2004
Statut
Membre
Dernière intervention
13 février 2008
-
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
-
Bonjour, je créé actuellement en driver ASIO sous forme de DLL, j'ai eu un exemple général de création d'un driver dans la SDK ASIO 2.2, mais tout est écrit en c++ et ce n'est pas très clair.

Mon problème actuellement est d'arriver à réécrire la déclaration de l'interface IUnknown dans ma dll, qui sera appelée par le logiciel qui chargera le pilote. Je dois aussi comprendre comment relier les déclaration des fonctions de l'interface aux fonctions que j'ai dans mes autres fichiers .c.

Voilà le code cpp que je voudrais traduire en C

#ifndef __ASIODRIVER_FWD_DEFINED__
#define __ASIODRIVER_FWD_DEFINED__
typedef interface IASIO IASIO;
#endif     /* __ASIODRIVER_FWD_DEFINED__ */

interface IASIO : public IUnknown
{

    virtual ASIOBool init(void *sysHandle) = 0;
    virtual void getDriverName(char *name) = 0;   
    virtual long getDriverVersion() = 0;
    virtual void getErrorMessage(char *string) = 0;   
    virtual ASIOError start() = 0;
    virtual ASIOError stop() = 0;
    virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels) = 0;
    virtual ASIOError getLatencies(long *inputLatency, long *outputLatency) = 0;
    virtual ASIOError getBufferSize(long *minSize, long *maxSize,long *preferredSize, long *granularity) = 0;
    virtual ASIOError canSampleRate(ASIOSampleRate sampleRate) = 0;
    virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate) = 0;
    virtual ASIOError setSampleRate(ASIOSampleRate sampleRate) = 0;
    virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources) = 0;
    virtual ASIOError setClockSource(long reference) = 0;
    virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0;
    virtual ASIOError getChannelInfo(ASIOChannelInfo *info) = 0;
    virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels,long bufferSize, ASIOCallbacks *callbacks) = 0;
    virtual ASIOError disposeBuffers() = 0;
    virtual ASIOError controlPanel() = 0;
    virtual ASIOError future(long selector,void *opt) = 0;
    virtual ASIOError outputReady() = 0;
};

Je voudrais avant tout comprendre ce fonctionnement par interface, car j'étais pour le moment habitué à l'appel de fonction dans une dll par getprocadresse.

Merci d'avance, à bientôt

http://www.rc-bot.com/bannieres/banniere468x60.jpg

5 réponses

Messages postés
966
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
4 mars 2010
4
Je suis pas sûr qu'on puisse traduire ça en C (fonction virtuelle pure...)
Mais pourquoi pas utiliser le C++ ? le COM c'est quand même très orienté objet...
Quant à la définition de IUnknown : dans
Messages postés
116
Date d'inscription
dimanche 26 septembre 2004
Statut
Membre
Dernière intervention
13 février 2008

Oui je pense que je vais devoir me diriger vers le C++, d'ailleurs j'ai essayé de recompiler le driver d'exemple avec dev-cpp, mais j'ai un problème d'exportation des fonctions dans la dll. Lorsque je regarde les exports de DllRegister et DllUnregister je trouve :

; dlltool --base-file C:\DOCUME~1\isen\LOCALS~1\Temp/cca01844.base --output-exp ASIO2DIGITAL.exp --dllname ASIO2DIGITAL.dll --output-def libASIO2DIGITAL.def --no-export-all-symbols --add-stdcall-alias --exclude-symbol=DllMainCRTStartup@12 --def C:\DOCUME~1\isen\LOCALS~1\Temp/cca01844.def --output-lib libASIO2DIGITAL.a
EXPORTS
    _Z17DllRegisterServerv@0 @ 1
    _Z19DllUnregisterServerv = _Z19DllUnregisterServerv@0 @ 2
    _Z19DllUnregisterServerv@0 @ 3
    _Z17DllRegisterServerv = _Z17DllRegisterServerv@0 @ 4

les _Z17 et _Z19 proviennent d'ou ?

Pour info je déclare mes fonctions à exporter comme je le faisais en C:

# define DLLEXPORT __declspec (dllexport)

DLLEXPORT HRESULT _stdcall DllUnregisterServer()

Faut-il proceder différemment en c++ ?

Snif, je suis de nouveau un débutant

http://www.rc-bot.com/bannieres/banniere468x60.jpg
Messages postés
116
Date d'inscription
dimanche 26 septembre 2004
Statut
Membre
Dernière intervention
13 février 2008

aller tiens je me répond tout seul, j'ai trouvé dans un exemple :

extern "C" HRESULT DLLEXPORT _stdcall DllRegisterServer()

extern "C" pour exporter les fonctions dans la DLL sans _Zxx, mais je ne sais toujours pas pourquoi ceci apparaissait.

http://www.rc-bot.com/bannieres/banniere468x60.jpg
Messages postés
966
Date d'inscription
samedi 3 avril 2004
Statut
Membre
Dernière intervention
4 mars 2010
4
Tes _Zxx ça doit être la décoration des noms de fonction.
Quant à extern "C" {...} c'est pour indiquer (je crois) l'utilisation de la décoration language C.
Messages postés
1910
Date d'inscription
vendredi 18 juin 2004
Statut
Modérateur
Dernière intervention
14 novembre 2014
13
Salut,
On peut tout faire avec le C. Il faut juste abandonner toutes les notions de POO et le confort qu'elles apportent.
En C, une interface COM est une structure contenant un pointeur vers une table de pointeurs sur toutes les fonctions (méthodes). Cette table s'appelle la VTable. Il faudra obligatoirement passer par elle pour appeler les fonctions de l'interface incluant celles de IUnknown comme AddRef() Release() etc.
Dans un fichier .h comme unknown.h, on trouve les deux déclarations. Une pour le C++ et l'autre pour le C.
L'avantage de travailler en C, c'est qu'il permet de comprendre comment les choses fonctionnent exactement.
Voici un excellent article sur l'utilisation des objets COM en C:
COM in plain C