Как передать изображение с помощью PInvoke - PullRequest
2 голосов
/ 16 января 2012

У меня есть C DLL, которая выполняет некоторую обработку изображения и возвращает результат.Поэтому я пытаюсь передать изображение со стороны .NET, но сейчас я застрял, и я не уверен, что это за типы, тонкости маршалинга или синтаксис.Так как я новичок, это могут быть все три.

Я могу вызывать другие функции в рассматриваемой DLL, так что, по крайней мере, некоторые из основ находятся на месте.Например, когда я звоню:

IntPtr versionIntPtr = GetDLLVersionNumber();
string version = Marshal.PtrToStringAnsi(versionIntPtr);
Console.WriteLine("DLL version number reported as: " + version);

, и это работает абсолютно нормально, выводит текущую версию DLL на консоль.

Когда я смотрю на пример кода C, который использует тот жефункция, кажется, использует функцию следующим образом:

unsigned char* ExtractImageInfo(const char* pixels, size_t width, size_t height)

(у меня также есть файл заголовка, где та же функция упоминается следующим образом:

... ExtractImageInformation(struct ImageData image, void* imageInformation);

, но я недействительно знаю, что это значит.)

Итак, моя попытка использовать эту функцию выглядит следующим образом:

Сначала я указываю интерфейс для DLL:

[DllImport("C:\\MyDLL", EntryPoint = "ExtractImageInfo", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern IntPtr ExtractImageInfo(IntPtr image, UInt32 imageWidth, UInt32 imageHeight); 

Затем,Я получаю изображение правильного типа и получаю его размеры:

Bitmap bitmap1 = (Bitmap)Image.FromFile("C:\\Images\\myImage.bmp");
UInt32 _imageWidth = Convert.ToUInt32(bitmap1.Width);
UInt32 _imageHeight = Convert.ToUInt32(bitmap1.Height);

Затем я получаю указатель на изображение (так как я думаю, что это то, что мне нужно передать):

IntPtr bitmap1Ptr = bitmap1.GetHbitmap();

А потом я вызываю функцию ...

IntPtr myProcessedImage;
myProcessedImage = ExtractImageInfo(bitmap1Ptr, _imageWidth, _imageHeight);

Но она не работает - я не возвращаю указатель на мои обработанные данные.Большая часть того, что меня интересует, заключается в том, правильно ли я передаю изображение, и правильный ли синтаксис для моего интерфейса к нативной функции.Я думаю, что, вероятно, ответ на оба вопроса может быть НЕТ!

Я только несколько дней читал и экспериментировал с PInvoke, поэтому, если кто-нибудь может указать мне на ошибку моих способов, я буду вечно благодарен: -)

1 Ответ

3 голосов
/ 16 января 2012
 unsigned char* ExtractImageInfo(const char* pixels, size_t width, size_t height)

Название аргумента настоятельно предполагает, что он хочет указатель на необработанные данные пикселей. Вы можете получить его из свойства Bitmap.LockBits (), BitmapData.Scan0. Не вызывайте UnlockBits (), пока функция не вернется.

Возвращаемый тип функции является серьезной проблемой управления памятью. Какой бы указатель на буфер не был возвращен, он почти наверняка должен быть освобожден. Вы не можете сделать это из управляемого кода, у вас нет доступа к распределителю, используемому этим кодом C, для вызова правильной версии free (). Вызовите эту функцию миллион раз и дважды проверьте, что у вас нет утечки памяти из-под контроля. Если вы сделаете это, то не сможете сделать это точно, потребуется оболочка C ++ / CLI, хотя шансы на ее правильную работу также довольно малы. Это плохо спроектированная функция, которую трудно использовать из любого кода, включая C.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...