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 :
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);
Et le bout de code utilisant 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
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
            }
        }
Là, soit mon delegate n'est jamais appelé, soit j'ai des "stack overflow" ou "corruption mémoire"
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