Ciao
Una volta che passi l'handle di sistema dell'immagine (quello che in C++ è un HBITMAP e in C# viene considerato un IntPtr) alla funzione scritta in C++, il problema del tipo di ritorno non si presenta più: se quello che devi fare è modificare un'immagine esistente (che quindi hai già caricato e di cui conosci già l'handle) non c'è bisogno di riottenere l'handle, perchè lo hai già. Per cui puoi impostare il tipo di ritorno su void, o al massimo su bool per ottenere o meno la riuscita della chiamata. Per quanto riguarda il tipo del parametro della funzione in C++, puoi definirlo semplicemente come HBITMAP, quindi questa diviene la firma della funzione C++:
extern "C" __declspec(dllexport) bool DisegnaQualcosa(HBITMAP image_in);
E questa una sua possibile implementazione:
extern "C" __declspec(dllexport) bool DisegnaQualcosa(HBITMAP image_in)
{
//Ottiene un'icona da disegnare sull'immagine
HICON icon = LoadIcon(NULL, IDI_HAND);
//Crea un DC
HDC hdc = CreateCompatibleDC(NULL);
//Salva lo stato del DC
int st1 = SaveDC(hdc);
//Seleziona l'immagine nel DC
if(!SelectObject(hdc, image_in))
{
//Se l'operazione fallisce libera la memoria e ritorna false
DeleteDC(hdc);
return false;
}
//Copia l'icona
DrawIcon(hdc, 0, 0, icon);
//Rilascia la memoria
RestoreDC(hdc, st1);
DeleteDC(hdc);
DestroyIcon(icon);
//ritorna true
return true;
}
Per richiamarla da C# il prototipo della funzione diventa questo:
[DllImport(@"percorso\nome.dll")]
static extern bool DisegnaQualcosa(IntPtr image_in);
E il modo di utilizzarla da C# potrebbe essere questo (in alternativa puoi mettere Bitmap come valore di ritorno):
bool DisegnaQualcosaWrapper(ref Bitmap image)
{
//Ottiene l'handle di immagine per la bitmap
IntPtr hImg = image.GetHbitmap();
//Esegue la funzione dalla dll
if (!DisegnaQualcosa(hImg))
{
//Elimina l'oggetto GDI e ritorna false
DeleteObject(hImg);
return false;
}
//A questo punto l'immagine non contiene i dati modificati, perchè
//sono memorizzati in hImg, quindi crea una nuova immagine da hImg
Bitmap newBmp = (Bitmap)Bitmap.FromHbitmap(hImg);
//La vecchia immagine diventa quella nuova
image = newBmp;
//ritorna true
return true;
}
Luca