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

C Discussion :

Communication avec un objet COM


Sujet :

C

  1. #1
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Mars 2013
    Messages : 32
    Points : 1 379
    Points
    1 379
    Par défaut Communication avec un objet COM
    Bonjour,
    Je travaille actuellement sur la programmation d'un robot industriel qui s'interface avec l'ordinateur avec un objet COM. Et bien sûr je dois m'interfacer en langage C alors que seul le cas de JavaScript est documenté par le constructeur...

    Je ne connais pas les objets COM, j'ai tout appris dessus via quelques liens :
    http://www.codeproject.com/Articles/...COM-in-plain-C
    http://www.codeguru.com/cpp/i-n/iepr...pplication.htm
    http://ccc.panitzco.com/mpanitz/COM_...InCInProc.html

    J'ai beau copier, analyser et réimplémenter les codes d'exemples, cela ne suffit pas.
    En fait, j'arrive à obtenir l'objet mais je ne parviens pas à utiliser les fonctionnalités qu'il est censé proposé, soit cela plante (genre la console crashe), soit j'ai un code d'erreur type 0xC0000005 qui est normalement une violation d'accès (je précise que je suis sous Windows XP SP3 avec les droits d'administrateur).

    Et cela fait plusieurs jours que je patine sans trouver une piste.

    Voici le code source en entier (je n'ai pas de .h volontairement dans un premier temps et les fonctions en commentaires font planter l'exécution tandis que les autres renvoient une erreur) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    #include <windows.h>
    #include <objbase.h>
    #include <initguid.h>
    #include <stdio.h>
    #include <OleAuto.h>
    #include <wchar.h>
    #include <string.h>
     
    #define INTERFACE   Rob5x
     
    //92507B34-D92D-4F8C-967E-6C5166C0F1F6
    DEFINE_GUID(IID_Rob5x, 0x92507b34, 0xd92d, 0x4f8c, 0x96, 0x7e, 0x6c, 0x51, 0x66, 0xc0, 0xf1, 0xf6);
     
    //5DD00CD6-E135-4799-A83F-62F06688700F
    DEFINE_GUID(CLSID_Rob5x, 0x5dd00cd6, 0xe135, 0x4799, 0xa8, 0x3f, 0x62, 0xf0, 0x66, 0x88, 0x70, 0x0f);
     
    DECLARE_INTERFACE_ (INTERFACE, IDispatch)
    {
        /* Implémentation de la classe IUnknown */
        STDMETHOD   (QueryInterface)                        (THIS_ GUID *, void **) PURE;
        STDMETHOD_  (ULONG, AddRef)                         (THIS) PURE;
        STDMETHOD_  (ULONG, Release)                        (THIS) PURE;
     
        /* De même pour la classe IDispatch */
        STDMETHOD_ (HRESULT, GetTypeInfoCount)              (THIS_ UINT *) PURE;
        STDMETHOD_ (HRESULT, GetTypeInfo)                   (THIS_ UINT, LCID, ITypeInfo **) PURE;
        STDMETHOD_ (HRESULT, GetIDsOfNames)                 (THIS_ REFIID, LPOLESTR *, UINT, LCID, DISPID *) PURE;
        STDMETHOD_ (HRESULT, Invoke)                        (THIS_ DISPID, REFIID, LCID, WORD, DISPPARAMS *, VARIANT *, EXCEPINFO *, UINT *) PURE;
     
        /* Méthodes de la classe spécifique au robot */
        STDMETHOD_  (ULONG, CloseComm)                      (THIS) PURE;
        STDMETHOD_  (ULONG, Energize)                       (THIS_ ULONG) PURE;
        STDMETHOD_  (BSTR, GetErrorInfo)                    (THIS_ ULONG) PURE;
        STDMETHOD_  (ULONG, GetCurrentPosition)             (THIS_ VARIANT) PURE;
        STDMETHOD_  (ULONG, GetString)                      (THIS_ VARIANT) PURE;
        STDMETHOD_  (ULONG, GotoHome)                       (THIS_ ULONG) PURE;
        STDMETHOD_  (ULONG, GotoPoint)                      (THIS_ BSTR, ULONG) PURE;
        STDMETHOD_  (ULONG, GotoPosition)                   (THIS_ long, long, long, long, long, ULONG) PURE;
        STDMETHOD_  (ULONG, GotoUserPosition)               (THIS_ ULONG) PURE;
        STDMETHOD_  (ULONG, InitRobot)                      (THIS) PURE;
        STDMETHOD_  (ULONG, MemPointPosition)               (THIS_ long, long, long, long, long, BSTR) PURE;
        STDMETHOD_  (ULONG, Move)                           (THIS_ ULONG, ULONG, ULONG, ULONG) PURE;
        STDMETHOD_  (ULONG, OpenComm)                       (THIS_ BSTR) PURE;
        STDMETHOD_  (ULONG, RestoreUserDefaultPosition)     (THIS) PURE;
        STDMETHOD_  (ULONG, SendString)                     (THIS_ BSTR) PURE;
        STDMETHOD_  (ULONG, SetSpeed)                       (THIS_ ULONG) PURE;
        STDMETHOD_  (ULONG, SetUserPosition)                (THIS_ long, long, long, long, long) PURE;
        STDMETHOD_  (ULONG, Wait)                           (THIS_ ULONG) PURE;
        STDMETHOD_  (ULONG, SetLimits)                      (THIS_ long, long, long, long, long) PURE;
        STDMETHOD_  (ULONG, RestoreDefaultLimits)           (THIS) PURE;
        STDMETHOD_  (ULONG, GetLimits)                      (THIS_ VARIANT) PURE;
        STDMETHOD_  (ULONG, SetToolParam)                   (THIS) PURE;
        STDMETHOD_  (LONG, GetToolParam)                    (THIS) PURE;
        STDMETHOD_  (ULONG, Align)                          (THIS_ ULONG) PURE;
        STDMETHOD_  (ULONG, GetVacuum)                      (THIS_ VARIANT) PURE;
        STDMETHOD_  (ULONG, Pump)                           (THIS_ ULONG) PURE;
        STDMETHOD_  (ULONG, Valve)                          (THIS_ ULONG) PURE;
        STDMETHOD_  (ULONG, OpenManualBox)                  (THIS) PURE;
        STDMETHOD_  (ULONG, GetSpeed)                       (THIS_ VARIANT) PURE;
        STDMETHOD_  (ULONG, WaitForManualBoxEnd)            (THIS) PURE;
        STDMETHOD_  (BSTR, GetSerialNumber)                 (THIS) PURE;
        STDMETHOD_  (ULONG, GetUserPosition)                (THIS_ VARIANT) PURE;
        STDMETHOD_  (ULONG, Calibrate)                      (THIS_ long) PURE;
        STDMETHOD_  (ULONG, GetSpeedStatus)                 (THIS) PURE;
        STDMETHOD_  (ULONG, GetSpeedNum)                    (THIS) PURE;
        STDMETHOD_  (ULONG, GetCurrentPositionStatus)       (THIS) PURE;
        STDMETHOD_  (BSTR, GetCurrentPositionStr)           (THIS) PURE;
        STDMETHOD_  (ULONG, GetLimitsStatus)                (THIS) PURE;
        STDMETHOD_  (BSTR, GetLimitsStr)                    (THIS) PURE;
        STDMETHOD_  (ULONG, GetVacuumStatus)                (THIS) PURE;
        STDMETHOD_  (ULONG, GetVacuumNum)                   (THIS) PURE;
        STDMETHOD_  (ULONG, GetUserPositionStatus)          (THIS) PURE;
        STDMETHOD_  (BSTR, GetUserPositionStr)              (THIS) PURE;
        STDMETHOD_  (ULONG, OpenPositionManager)            (THIS_ BSTR) PURE;
        STDMETHOD_  (ULONG, WaitForPositionManagerEnd)      (THIS) PURE;
        STDMETHOD_  (BSTR, GetPositionFile)                 (THIS) PURE;
        STDMETHOD   (SetPositionFile)                       (THIS_ BSTR) PURE;
        STDMETHOD_  (ULONG, Laser)                          (THIS_ ULONG) PURE;
        STDMETHOD_  (ULONG, SetAccel)                       (THIS_ ULONG) PURE;
        STDMETHOD_  (ULONG, GetAccel)                       (THIS_ VARIANT) PURE;
        STDMETHOD_  (ULONG, GetAccelStatus)                 (THIS) PURE;
        STDMETHOD_  (ULONG, GetAccelNum)                    (THIS) PURE;
    };
     
    typedef struct {
        Rob5xVtbl       *lpVtbl;
        DWORD           count;
        char            buffer[80];
    } MyRob5x;
     
     
    /* Deux fonctions pour traduire les chaines de type BSTR vers des types classiques */
    void BSTRtoASC(BSTR str, char *strRet)
    {
        if(str != NULL) {
           ULONG length = WideCharToMultiByte(CP_ACP, 0, str, SysStringLen(str), NULL, 0, NULL, NULL);
           strRet = malloc(sizeof(char)*length);
           length = WideCharToMultiByte(CP_ACP, 0, str, SysStringLen(str), strRet, length, NULL, NULL);
           strRet[length] = '\0';
        }
    }
     
    void ASCtoBSTR(char *str, BSTR *strRet)
    {
        if(str != NULL) {
            ULONG length = strlen(str);
            int ResultLength = MultiByteToWideChar (CP_ACP,MB_PRECOMPOSED, str,length,NULL,0);
            *strRet = SysAllocStringLen(NULL, ResultLength);
            MultiByteToWideChar (CP_ACP,MB_PRECOMPOSED, str,length,*strRet,ResultLength);
        }
    }
     
    int main(void)
    {
        LPVOID *pIFace = NULL;
        Rob5x *Robot = NULL;
        HRESULT resultat = 0;
        ULONG retVal;
        IClassFactory *classFactory = NULL;
        char *chaine = NULL;
        wchar_t chaineW[] = L"COM3";
        BSTR chaineBSTR = NULL;
     
        chaineBSTR = SysAllocStringLen(chaineW, sizeof(chaineW));
     
        /* On récupère l'objet, on lance une instance et on tente une communication avec le robot */
        if(!CoInitialize(NULL)) {
     
            resultat = CoGetClassObject(&CLSID_Rob5x, CLSCTX_ALL, 0, &IID_IClassFactory, &classFactory);
     
            if(resultat)
                printf("Erreur pour obtenir l'objet: 0x%08.8X\n", resultat);
            else {
                resultat = classFactory->lpVtbl->CreateInstance(classFactory, 0, &IID_Rob5x, &Robot);
                if(resultat) {
                    classFactory->lpVtbl->Release(classFactory);
                    printf("Erreur de creation d'instance: 0x%08.8X\n", resultat);
                } else {
                    classFactory->lpVtbl->Release(classFactory);
     
                    ASCtoBSTR("COM3", &chaineBSTR);
                    wprintf(L"String: %s\n", chaineBSTR);
                    retVal = Robot->lpVtbl->OpenComm(Robot, chaineBSTR);
                    //Robot->lpVtbl->OpenManualBox(Robot);
     
                    printf("Valeur : 0x%08.8X", retVal);
                    //wprintf(L"Numero de serie : %s\n", Robot->lpVtbl->GetSerialNumber(Robot));
     
                    Robot->lpVtbl->CloseComm(Robot);
                    Robot->lpVtbl->Release(Robot);
     
                    CoUninitialize();
     
                    return 0;
                }
            }
        }
        printf("resultat : %d\n", resultat);
     
        return 0;
    }
    Je poste en supplément les informations sur l'objet COM dont il est question.

    Il hérite des interfaces mentionnés dans le code, et voici le rendu de ses propriétés obtenus via l'outil oleview.exe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    // Generated .IDL file (by the OLE/COM Object Viewer)
    //
    // typelib filename: Rob5x.exe
     
    [
      uuid(3CF4288A-9CB4-44DE-8CB2-8EDC34EB5A7C),
      version(1.0),
      helpstring("RobX 1.0 Type Library"),
      custom(DE77BA64-517C-11D1-A2DA-0000F8773CE9, 100663657),
      custom(DE77BA63-517C-11D1-A2DA-0000F8773CE9, 1360058814),
      custom(DE77BA65-517C-11D1-A2DA-0000F8773CE9, Created by MIDL version 6.00.0361 at Tue Feb 05 11:06:53 2013
    )
     
    ]
    library RobXLib
    {
        // TLib :     // TLib : OLE Automation : {00020430-0000-0000-C000-000000000046}
        importlib("stdole2.tlb");
     
        // Forward declare all types defined in this typelib
        interface IRobX;
     
        [
          uuid(5DD00CD6-E135-4799-A83F-62F06688700F),
          helpstring("CoRobX Class")
        ]
        coclass CoRobX {
            [default] interface IRobX;
        };
     
        [
          odl,
          uuid(92507B34-D92D-4F8C-967E-6C5166C0F1F6),
          helpstring("IRobX Interface"),
          dual,
          nonextensible,
          oleautomation
        ]
        interface IRobX : IDispatch {
            [id(0x00000001), helpstring("method CloseComm")]
            HRESULT CloseComm([out, retval] unsigned long* retVal);
            [id(0x00000002), helpstring("method Energize")]
            HRESULT Energize(
                            [in] unsigned long activate,
                            [out, retval] unsigned long* retVal);
            [id(0x00000003), helpstring("method GetErrorInfo")]
            HRESULT GetErrorInfo(
                            [in] unsigned long errorCode,
                            [out, retval] BSTR* retStr);
            [id(0x00000004), helpstring("method GetCurrentPosition")]
            HRESULT GetCurrentPosition(
                            [in] VARIANT coordArray,
                            [out, retval] unsigned long* retVal);
            [id(0x00000005), helpstring("method GetString")]
            HRESULT GetString(
                            [in] VARIANT readBytes,
                            [out, retval] unsigned long* retVal);
            [id(0x00000006), helpstring("method GotoHome")]
            HRESULT GotoHome(
                            [in] unsigned long timeout,
                            [out, retval] unsigned long* retVal);
            [id(0x00000007), helpstring("method GotoPoint")]
            HRESULT GotoPoint(
                            [in] BSTR name,
                            [in] unsigned long timeout,
                            [out, retval] unsigned long* retVal);
            [id(0x00000008), helpstring("method GotoPosition")]
            HRESULT GotoPosition(
                            [in] long X,
                            [in] long Y,
                            [in] long Z,
                            [in] long W,
                            [in] long P,
                            [in] unsigned long timeout,
                            [out, retval] unsigned long* retVal);
            [id(0x00000009), helpstring("method GotoUserPosition")]
            HRESULT GotoUserPosition(
                            [in] unsigned long timeout,
                            [out, retval] unsigned long* retVal);
            [id(0x0000000a), helpstring("method InitRobot")]
            HRESULT InitRobot([out, retval] unsigned long* retVal);
            [id(0x0000000b), helpstring("method MemPointPosition")]
            HRESULT MemPointPosition(
                            [in] long X,
                            [in] long Y,
                            [in] long Z,
                            [in] long W,
                            [in] long P,
                            [in] BSTR name,
                            [out, retval] unsigned long* retVal);
            [id(0x0000000c), helpstring("method Move")]
            HRESULT Move(
                            [in] unsigned long X,
                            [in] unsigned long Y,
                            [in] unsigned long Z,
                            [in] unsigned long timeout,
                            [out, retval] unsigned long* retVal);
            [id(0x0000000d), helpstring("method OpenComm")]
            HRESULT OpenComm(
                            [in] BSTR portName,
                            [out, retval] unsigned long* retVal);
            [id(0x0000000e), helpstring("method RestoreUserDefaultPosition")]
            HRESULT RestoreUserDefaultPosition([out, retval] unsigned long* retVal);
            [id(0x0000000f), helpstring("method SendString")]
            HRESULT SendString(
                            [in] BSTR bytesToSend,
                            [out, retval] unsigned long* retVal);
            [id(0x00000010), helpstring("method SetSpeed")]
            HRESULT SetSpeed(
                            [in] unsigned long speed,
                            [out, retval] unsigned long* retVal);
            [id(0x00000011), helpstring("method SetUserPosition")]
            HRESULT SetUserPosition(
                            [in] long X,
                            [in] long Y,
                            [in] long Z,
                            [in] long W,
                            [in] long P,
                            [out, retval] unsigned long* retVal);
            [id(0x00000012), helpstring("method Wait")]
            HRESULT Wait(
                            [in] unsigned long millisecs,
                            [out, retval] unsigned long* retVal);
            [id(0x00000013), helpstring("method SetLimits")]
            HRESULT SetLimits(
                            [in] long Xmin,
                            [in] long Xmax,
                            [in] long Ymin,
                            [in] long Ymax,
                            [in] long Zmin,
                            [out, retval] unsigned long* retVal);
            [id(0x00000014), helpstring("method RestoreDefaultLimits")]
            HRESULT RestoreDefaultLimits([out, retval] unsigned long* retVal);
            [id(0x00000015), helpstring("method GetLimits")]
            HRESULT GetLimits(
                            [in] VARIANT Limits,
                            [out, retval] unsigned long* retVal);
            [id(0x00000016), helpstring("method SetToolParam")]
            HRESULT SetToolParam(
                            [in] long ToolLength,
                            [out, retval] unsigned long* retVal);
            [id(0x00000017), helpstring("method GetToolParam")]
            HRESULT GetToolParam([out, retval] long* ToolLength);
            [id(0x00000018), helpstring("method Align")]
            HRESULT Align(
                            [in] unsigned long activate,
                            [out, retval] unsigned long* retVal);
            [id(0x00000019), helpstring("method GetVacuum")]
            HRESULT GetVacuum(
                            [in] VARIANT vacuum,
                            [out, retval] unsigned long* retVal);
            [id(0x0000001a), helpstring("method Pump")]
            HRESULT Pump(
                            [in] unsigned long activate,
                            [out, retval] unsigned long* retVal);
            [id(0x0000001b), helpstring("method Valve")]
            HRESULT Valve(
                            [in] unsigned long open,
                            [out, retval] unsigned long* retVal);
            [id(0x0000001c), helpstring("method OpenManualBox")]
            HRESULT OpenManualBox([out, retval] unsigned long* retVal);
            [id(0x0000001d), helpstring("method GetSpeed")]
            HRESULT GetSpeed(
                            [in] VARIANT speed,
                            [out, retval] unsigned long* retVal);
            [id(0x0000001e), helpstring("method WaitForManualBoxEnd")]
            HRESULT WaitForManualBoxEnd([out, retval] unsigned long* retVal);
            [id(0x0000001f), helpstring("method GetSerialNumber")]
            HRESULT GetSerialNumber([out, retval] BSTR* serialNumber);
            [id(0x00000020), helpstring("method GetUserPosition")]
            HRESULT GetUserPosition(
                            [in] VARIANT userPosition,
                            [out, retval] unsigned long* retVal);
            [id(0x00000021), helpstring("method Calibrate")]
            HRESULT Calibrate(
                            [in] long ask,
                            [out, retval] unsigned long* retVal);
            [id(0x00000022), helpstring("method GetSpeedStatus")]
            HRESULT GetSpeedStatus([out, retval] unsigned long* retVal);
            [id(0x00000023), helpstring("method GetSpeedNum")]
            HRESULT GetSpeedNum([out, retval] unsigned long* speed);
            [id(0x00000024), helpstring("method GetCurrentPositionStatus")]
            HRESULT GetCurrentPositionStatus([out, retval] unsigned long* retVal);
            [id(0x00000025), helpstring("method GetCurrentPositionStr")]
            HRESULT GetCurrentPositionStr([out, retval] BSTR* coordStr);
            [id(0x00000026), helpstring("method GetLimitsStatus")]
            HRESULT GetLimitsStatus([out, retval] unsigned long* retVal);
            [id(0x00000027), helpstring("method GetLimitsStr")]
            HRESULT GetLimitsStr([out, retval] BSTR* limitsStr);
            [id(0x00000028), helpstring("method GetVacuumStatus")]
            HRESULT GetVacuumStatus([out, retval] unsigned long* retVal);
            [id(0x00000029), helpstring("method GetVacuumNum")]
            HRESULT GetVacuumNum([out, retval] unsigned long* vacuum);
            [id(0x0000002a), helpstring("method GetUserPositionStatus")]
            HRESULT GetUserPositionStatus([out, retval] unsigned long* retVal);
            [id(0x0000002b), helpstring("method GetUserPositionStr")]
            HRESULT GetUserPositionStr([out, retval] BSTR* coordStr);
            [id(0x0000002c), helpstring("method OpenPositionManager")]
            HRESULT OpenPositionManager(
                            [in] BSTR positions,
                            [out, retval] unsigned long* retVal);
            [id(0x0000002d), helpstring("method WaitForPositionManagerEnd")]
            HRESULT WaitForPositionManagerEnd([out, retval] unsigned long* retVal);
            [id(0x0000002e), propget, helpstring("property PositionFile")]
            HRESULT PositionFile([out, retval] BSTR* filePath);
            [id(0x0000002e), propput, helpstring("property PositionFile")]
            HRESULT PositionFile([in] BSTR filePath);
            [id(0x0000002f), helpstring("method Laser")]
            HRESULT Laser(
                            [in] unsigned long activate,
                            [out, retval] unsigned long* retVal);
            [id(0x00000030), helpstring("method SetAccel")]
            HRESULT SetAccel(
                            [in] unsigned long accel,
                            [out, retval] unsigned long* retVal);
            [id(0x00000031), helpstring("method GetAccel")]
            HRESULT GetAccel(
                            [in] VARIANT accel,
                            [out, retval] unsigned long* retVal);
            [id(0x00000032), helpstring("method GetAccelStatus")]
            HRESULT GetAccelStatus([out, retval] unsigned long* retVal);
            [id(0x00000033), helpstring("method GetAccelNum")]
            HRESULT GetAccelNum([out, retval] unsigned long* speed);
        };
    };

    Je vous remercie d'avance si vous avez une idée sur le sujet.

    Si vous avez des liens sur le sujet en complément, cela m'intéresse également.

  2. #2
    Membre expert
    Avatar de Metalman
    Homme Profil pro
    Enseignant-Chercheur
    Inscrit en
    Juin 2005
    Messages
    1 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Enseignant-Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 049
    Points : 3 532
    Points
    3 532
    Par défaut
    Regarde la source que j'ai mise (WMI_Interrogator).
    Je n'ai pas vraiment appris à me servir des objets COM en pur C, mais j'ai trouvé un exemple qui fonctionnait, et je l'ai réutilisé.

    Mon but était d'accéder à la CMI/WMI de Windows, mais je pense que tu pourras retirer l'énorme bloc qui ne te sert à rien.
    De plus, j'ai laissé le lien vers le site de celui à qui j'ai récupéré les bouts de code très utiles.

    Bon courage !

    EDIT : Lien du WMI Interrogator
    --
    Metalman !

    Attendez 5 mins après mes posts... les EDIT vont vite avec moi...
    Les flags de la vie : gcc -W -Wall -Werror -ansi -pedantic mes_sources.c
    gcc -Wall -Wextra -Werror -std=c99 -pedantic mes_sources.c
    (ANSI retire quelques fonctions comme strdup...)
    L'outil de la vie : valgrind --show-reachable=yes --leak-check=full ./mon_programme
    Et s'assurer que la logique est bonne "aussi" !

    Ma page Developpez.net

  3. #3
    Rédacteur
    Avatar de Vincent Rogier
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 373
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 373
    Points : 5 307
    Points
    5 307
    Par défaut
    tu ne peux pas utiliser la coclass directement..... Il faut utiliser l'interface IRobX à la place....
    Vincent Rogier.

    Rubrique ORACLE : Accueil - Forum - Tutoriels - FAQ - Livres - Blog

    Vous voulez contribuer à la rubrique Oracle ? Contactez la rubrique !

    OCILIB (C Driver for Oracle)

    Librairie C Open Source multi-plateformes pour accéder et manipuler des bases de données Oracle

  4. #4
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Mars 2013
    Messages : 32
    Points : 1 379
    Points
    1 379
    Par défaut
    Je te remercie pour le code source, je l'ai regardé.
    Cependant quelque chose me surprend, j'ai l'impression que ton cas fonctionne parce que le modèle utilisé est défini dans les includes directement car cela semble être une interface spéciale de Windows. Je me souviens avoir essayé avec une simple table de pointeurs de fonction (et donc sans la création de la grosse interface) mais il m'envoyait balader car il ne connaissait pas le but des fonctions (alors que pour toi, cela semble venir directement). Je vais tenter quelque chose dans ce sens là malgré tout, on ne sait jamais.

    Sinon pour l'histoire de la coclass, dans quel sens tu en parles ? Est-ce que je dois réaliser une étape supplémentaire pour accéder à l'interface qui contient les méthodes (dans la fonction principale) ? Ou est-ce que je dois crée une interface supplémentaire pour mieux correspondre au modèle de l'objet COM avec lequel je souhaite communiquer et ainsi tout obtenir de manière propre (donc plutôt dans la définition de l'interface) ?

    Je vous remercie pour vos pistes, je ne suis pas contre quelques éclaircissements supplémentaires. Je suis bien entendu preneurs de liens pour comprendre, la doc de Microsoft sur les objets COM est limité pour le langage C et à part ce que j'ai mentionné je n'ai pas trouvé plus qui soit pertinent et didactique.

    Je vous remercie donc d'avance une nouvelle fois.

  5. #5
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Mars 2013
    Messages : 32
    Points : 1 379
    Points
    1 379
    Par défaut
    J'ai lu beaucoup de documentation et de code durant le week-end et je ne comprends pas vos remarques dans le sens où je en vois pas l'erreur.

    En effet, j'utilise bien normalement l’interface IRobX, la coclass que j’instancie au départ et que je libère peu après ne sert qu'à récupérer l'interface, je ne vois nul part dans le code où je l'utilise au lieu de l'interface. De plus, le compilateur ne m'aurait pas prévenu d'un tel problème ?

    Je trouve mon problème étrange car les codes dont je m'inspire fonctionnent et pas le mien et pourtant tout semble correspondre à ce que je souhaite réellement faire.

  6. #6
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void BSTRtoASC(BSTR str, char *strRet)
    {
        if(str != NULL) {
           ULONG length = WideCharToMultiByte(CP_ACP, 0, str, SysStringLen(str), NULL, 0, NULL, NULL);
           strRet = malloc(sizeof(char)*length);
           length = WideCharToMultiByte(CP_ACP, 0, str, SysStringLen(str), strRet, length, NULL, NULL);
           strRet[length] = '\0';
        }
    }
    Quand les fonctions utilitaires basiques sont erronées, inutile de regarder le code qui les utilise tant que les erreurs ne sont pas corrigées.

    Je suivrai ce sujet d'un peu plus près par la suite, vu que je m'y connais un peu en COM.

    Edit:
    • Pourquoi utiliser explicitement la class factory? La fonction CoCreateInstance fait ça pour toi, en appelant CoGetClassObject(CLSID IClassFactory) et CreateInstance().
    • if(resultat) est mauvais. On doit soit explicitement comparer à S_OK, soit utiliser les macros SUCCEEDED() et FAILED().
    • Le SysAllocStringLen() sur un sizeof d'une chaîne large me paraît bizarre. Pourquoi allouer dix wchar_t pour en écrire seulement cinq, au lieu d'utiliser simplement SysAllocString(L"COM3") ?
    • Ne pas oublier les appels à SysFreeString().


    Edit2: Une minute, le code C ne correspond pas du tout à l'IDL!!
    L'IDL décrit une interface duale compatible Automation (c'est-à-dire qu'elle ne retourne que des HRESULT, ses valeurs de retour étant toujours passées par pointeur au dernier paramètre), alors que le code C décrit une interface retournant directement ses valeurs de retour!
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Mars 2013
    Messages : 32
    Points : 1 379
    Points
    1 379
    Par défaut
    Je te remercie d'apporter des idées d'amélioration, j'admets volontiers de faire des erreurs dans ce domaine car j'apprends sans cesse pour manipuler au mieux cet API que je ne connais pas. Sans doute qu'il me faudra un peu de temps pour que cela se passe bien.

    Cependant je viens de trouver la solution à mon problème, en effet les prototypes des fonctions de l'objet n'étaient pas bon. Oleview.exe m'a présenté deux manière de faire (un avec la sortie via un pointeur en paramètre, l'autre avec la sortie directe sans pointeur en paramètre, c'est le second choix qui était apparemment le bon).

    A part ça je n'ai rien changé et cela fonctionne. Je prends malgré tout compte de tes remarques pour améliorer le code en efficacité et éviter des effets de bords.

    EDIT : oui tu as remarqué le problème que j'avais identifié. Mais pourquoi oleview.exe m'a présenté également la manière de faire que j'ai effectué ? je trouve cela étrange...

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    La façon que tu as faite, c'est celle des dispinterfaces: C'est la façon dont le code de haut niveau (Visual Basic, etc.) voit l'interface.

    En faite une interface duale, c'est une interface + une dispinterface: (sachant qu'à bas niveau, seule la "vraie" interface existe; la dispinterface est une illusion crée par IDispatch).

    PS: N'oublie pas, les sept premières méthodes (celles de IUnknown et IDispatch), elles, sont bonnes, en dehors du petit détail mentionné ci-après (et encore, même avec, ça reste bon).

    PPS: STDMETHOD_(HRESULT, Toto) est juste une façon plus longue d'écrire STDMETHOD(Toto).
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  9. #9
    Membre expérimenté

    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2013
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

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

    Informations forums :
    Inscription : Mars 2013
    Messages : 32
    Points : 1 379
    Points
    1 379
    Par défaut
    J'ai contacté le fabricant du robot pour avoir plus d'informations.
    En fait les fonctions qui attendent un VARIANT en paramètre sont à passer par référence pour que cela fonctionne. Ils ont mis à côté spécialement des fonctions qui renvoient des chaines de caractères pour les langages qui ne supportent pas cette possibilité comme le C ou Python.

    Du coup je n'ai plus à me préoccuper des types VARIANT.
    Je vous remercie pour votre aide et désolé pour le dérangement pour qu'au final cela soit impossible...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [COM] PHP en communication avec l'objet COM
    Par joe_le_mort dans le forum Bibliothèques et frameworks
    Réponses: 4
    Dernier message: 22/05/2012, 14h57
  2. Problème avec un objet COM
    Par Khrysby dans le forum Framework .NET
    Réponses: 2
    Dernier message: 28/11/2007, 19h33
  3. Réponses: 1
    Dernier message: 06/02/2007, 17h24
  4. [COM] Problème avec l'objet COM
    Par Commodore dans le forum Bibliothèques et frameworks
    Réponses: 1
    Dernier message: 16/05/2006, 20h36
  5. Réponses: 1
    Dernier message: 21/10/2005, 13h08

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