Bonjour
tous est dans le titre: peut on utiliser une DLL DotNet dans un programme en C? et si oui comment doit on faire?
Cordialement.
Bonjour
tous est dans le titre: peut on utiliser une DLL DotNet dans un programme en C? et si oui comment doit on faire?
Cordialement.
Tu peux, mais uniquement en tant que composant COM.
Ta DLL doit donc être COM-Visible, ainsi que les types que tu veux exposer (classes et interfaces) qui doivent avoir un UUID correctement défini.
Ensuite, tu dois définir les mêmes interfaces en C (ou bien, regénérer un fichier d'en-tête à partir de la Type Library, en utilisant le programme OLEVIEW.EXE livré avec Visual).
Une fois cela fait, tu pourras utiliser ta classe .Net comme simple classe COM (simplement, ça ne s'enregistre pas avec regsvr32.exe, mais avec un autre programme, il me semble que c'est regasm.exe).
Pas sous la main, mais il me semble qu'il y avait un tuto ou un article quelque part sur dvp (le site, pas le forum)
Là, ce n'est pas seulement du COM Interop, c'est du COM Interop + Late Binding (utilisation de l'interface IDispatch).
Tu peux aussi bien faire ça en C qu'en C++.
Pour la peine, une traduction de ce code en C (plus quelques corrections):
Code C : 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 //Exemple de COM Interop en C++ sur le bloc de nico-pyright. //Corrigé et Traduit en C le 2008-02-12 Ma pour Jayceblaster #include <windows.h> #include <stdio.h> #include <tchar.h> int _tmain(void) { CLSID clsID; CoInitialize(NULL); //Création de l'objet if (SUCCEEDED(CLSIDFromProgID(OLESTR("assembly.MaClasse"), &clsID))) { IDispatch *pDisp = NULL; if (SUCCEEDED(CoCreateInstance(&clsID, NULL, CLSCTX_ALL, &IID_IDispatch, (void**)&pDisp))) { //Appelle de la méthode Print OLECHAR *methodName = OLESTR("Print"); DISPID dispid; if (SUCCEEDED(pDisp->lpVtbl->GetIDsOfNames(pDisp, &IID_NULL, &methodName,1, GetUserDefaultLCID(), &dispid))) { DISPPARAMS param; param.cArgs=0; param.rgvarg=NULL; param.cNamedArgs=0; param.rgdispidNamedArgs=NULL; if (SUCCEEDED(pDisp->lpVtbl->Invoke(pDisp, dispid, &IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, ¶m, NULL, NULL, NULL))) { _putts("OK!"); } } pDisp->lpVtbl->Release(pDisp), pDisp=NULL; } } CoUninitialize(); return 0; }
Et voici une version plus robuste, séparée en fonctions, et avec une gestion (minimale) d'erreur:
Code C : 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 //Exemple de COM Interop en C++ sur le bloc de nico-pyright. //Corrigé et Traduit en C le 2008-02-12 Ma pour Jayceblaster #define COBJMACROS #include <windows.h> #include <stdio.h> #include <tchar.h> HRESULT faire_quelquechose_avec_objet(IDispatch *pDisp) { HRESULT hr; //Recherche de la méthode Print OLECHAR *methodName = OLESTR("Print"); DISPID dispid; hr = IDispatch_GetIDsOfNames(pDisp, &IID_NULL, &methodName,1, GetUserDefaultLCID(), &dispid); if(FAILED(hr)) _tprintf(_T("GetIDsOfNames() failed with HRESULT 0x%08lX.\n"), hr); else { //Appel de la méthode Print DISPPARAMS param; param.cArgs=0; param.rgvarg=NULL; param.cNamedArgs=0; param.rgdispidNamedArgs=NULL; hr = IDispatch_Invoke(pDisp, dispid, &IID_NULL, GetUserDefaultLCID(), DISPATCH_METHOD, ¶m, NULL, NULL, NULL); if(FAILED(hr)) _tprintf(_T("Invoke() failed with HRESULT 0x%08lX.\n"), hr); else { _putts("OK!"); } } return hr; } int com_tmain(void) { HRESULT hr; int ret = EXIT_FAILURE; hr = CoInitialize(NULL); if(FAILED(hr)) _tprintf(_T("CoInitialize() failed with HRESULT 0x%08lX.\n"), hr); else { //Recherche de la classe de l'objet. CLSID clsID; hr = CLSIDFromProgID(OLESTR("assembly.MaClasse"), &clsID); if(FAILED(hr)) _tprintf(_T("CLSIDFromProgID() failed with HRESULT 0x%08lX.\n"), hr); else { //Création de l'objet IDispatch *pDisp = NULL; hr = CoCreateInstance(&clsID, NULL, CLSCTX_ALL, &IID_IDispatch, (void**)&pDisp); if(FAILED(hr)) _tprintf(_T("CoCreateInstance() failed with HRESULT 0x%08lX.\n"), hr); else { hr = faire_quelquechose_avec_objet(pDisp); if(SUCCEEDED(hr)) ret = EXIT_SUCCESS; IDispatch_Release(pDisp), pDisp=NULL; } } CoUninitialize(); } return ret; }
j'ai fait un CoInitialize dans mon programme en C++ mais c'est pas reconnu pourquoi? (desolé je suis pas un crac en C++![]()
Il devrait être reconnu du moment que tu as inclus <windows.h>...
Est-ce une erreur de compilation ou d'édition de liens ?
Dans ce cas, je ne vois pas d'où peut venir l'erreur, à moins que tu l'aies mal tapé (tu as bien inclus <windows.h>, hein?)
Si le problème persiste, essaie en incluant aussi <objbase.h>, qui d'après l'aide, contient la déclaration de la fonction...
Je viens de testé, et on dirait que <windows.h> n'inclut pas automatiquement <objbase.h> si WIN32_LEAN_AND_MEAN est défini. C'était le cas, non ?
(à moins que tu soies sous MinGW: Je suppose que tu es sous Visual, puisque tu fais aussi du C#)
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager