Bonjour,
j'ai un "petit" souci avec une DLL écrite en C++ non managé et que je voudrais utiliser en C# et forcément ça ne marche pas.
Sachant que je n'y connais quasiment rien en C++, je ne sais pas trop où aller et quoi modifier...
Dans le code C++, j'ai ceci :
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 typedef int (CALLBACK* DS_SNAP_PROC)(BYTE *pImageBuffer, DS_DATA_TYPE TYPE, LPVOID lpContext); #ifdef DLL_EXPORT #define DT_API extern "C" __declspec(dllexport) #else #define DT_API extern "C" __declspec(dllimport) #endif /*============================================================== Name: CameraInit Desc: Initialize video equipment Param: uiResolution Resolution index hWndDisplay Video display control handle lpThreadparam Video thread create address Return: Call returns a STATUS_OK on success,otherwise returns an error code Note: --------------------------------------------------------------*/ DT_API DS_CAMERA_STATUS _stdcall CameraInit(DS_SNAP_PROC pCallbackFunction, IN DS_RESOLUTION uiResolution, IN HWND hWndDisplay, IN LPVOID lpThreadparam );
J'ai traduit en C#, en prenant des sources à droite à gauche, ce qui donne ceci :
Et le bout de code utilisant ceci :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 [System.Runtime.InteropServices.UnmanagedFunctionPointerAttribute(System.Runtime.InteropServices.CallingConvention.StdCall)] unsafe public delegate int DS_SNAP_PROC(byte* pImageBuffer, DS_DATA_TYPE TYPE, System.IntPtr lpContext); [System.Runtime.InteropServices.DllImportAttribute("DICAMSDK.dll", EntryPoint = "CameraInit")] public static extern DS_CAMERA_STATUS CameraInit(DS_SNAP_PROC pCallbackFunction, DS_RESOLUTION uiResolution, System.IntPtr hWndDisplay, System.IntPtr lpThreadparam);
Là, soit mon delegate n'est jamais appelé, soit j'ai des "stack overflow" ou "corruption mémoire"
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 public static DS_SNAP_PROC MyDelegate; public static byte[] MyBuffer = new byte[(640*480*3)+512]; unsafe public static byte* pMyBuffer; unsafe public static int MyProc(byte* pBuffer, DS_DATA_TYPE pDataType, IntPtr Pointeur) { Console.WriteLine("Begin delegate"); int Width = 0, Height = 0; DS_DATA_TYPE DataType = pDataType; DS_CAMERA_STATUS Statut; Statut = MonWrapper.CameraGetImageSize(ref Width, ref Height); Console.WriteLine("Inside delegate, statut = " + Statut + ", Width : " + Width + ", Heigth : " + Height); pMyBuffer = pBuffer; return 1; } public Mon_Constructeur(IntPtr pHandle1, IntPtr pHandle2) { unsafe { MyDelegate = new DS_SNAP_PROC(MyProc); fixed (byte* pMyBuffer = &MyBuffer[0]) ; MonWrapper.CameraInit(MyDelegate, (DS_RESOLUTION)0, pHandle1, pHandle2); Thread.Sleep(250); // Initial timeout Console.WriteLine("Play : " + MonWrapper.CameraPlay(DS_SNAP_MODE.SNAP_MODE_CONTINUATION)); // Gives STATUS_OK } }
Je me dis qu'il doit manquer des "Marshal" un peu partout, mais je ne sais pas où ni quoi.
Là je suis un peu coincé, je pars dans tous les sens sans trop savoir quoi faire
Pour info, j'ai pris le parti de faire ce wrapper en C# car je n'y connais rien en C++. Mais j'ai le code source complet, sauf qu'il s'agit d'un code écrit à la base en VC++ 6.0 natif et que je n'arrive pas à compiler avec VS2008
Sinon, j'aurais bien essayé de rendre le code C++ manageable, si possible.
Que me conseillez-vous ? Dans quelle direction aller de préférence ? (je sens bien le C++ managé, non ?)
Merci d'avance à toute âme charitable
________
Christophe
Partager