2013-06-28 4 views
4

Есть ли у кого-нибудь идея, если в качестве общего аргумента можно использовать примитивные типы.Указатели как генераторы C#

Обратите внимание, прежде чем вы начнете говорить о том, как я не должен использовать указатели.

Изображения представляют собой необработанные массивы данных, выделенные с использованием IPP, для большей части я буду использовать IPP, эта часть представляет собой преобразование из неуправляемых в управляемые данные в предпочтительном формате, когда требуется индивидуальная обработка данных не поддерживаемым IPP способом или предпочтительнее.

мне нужны следующие функции в байте, поплавок, короткие комбинации, и вместо того, чтобы писать все комбинации явными, я предпочел бы некоторую общую/шаблон вещь в стиле

private static unsafe List<PixelF> GetPixels<Timg,Tmask>(
    VMImage img, 
    int band, 
    VMImage imgMask, 
    int bandMask) 

где Timg и TMask могут быть один (байт, короткий или поплавок)

прямо сейчас, одна функция выглядит так.

private static unsafe List<PixelF> GetPixels_FloatImg_ByteMask(
    VMImage img, 
    int band, 
    VMImage imgMask, 
    int bandMask) 
{ 
    List<PixelF> pixValues = new List<PixelF>(); 
    int r, c; 
    int imgSrcOffset = img.LineLength - img.Width; 
    int imgMaskOffset = imgMask.LineLength - imgMask.Width; 
    float* pf_imgSrc = (float*)img.GetRoiPointer(band); 
    byte* pb_imgMask = (byte*)imgMask.GetRoiPointer(bandMask); 
    for (r = 0; r < img.Height; r++) // Loop over rows 
    { 
    for (c = 0; c < img.Width; c++) // Loop over columns 
    { 
     if (*pb_imgMask > 0) 
     { 
     pixValues.Add(new PixelF(c, r, (float)*pf_imgSrc)); 
     } 
     ++pf_imgSrc; 
     ++pb_imgMask; 
    } 
    pf_imgSrc += imgSrcOffset; 
    pb_imgMask += imgMaskOffset; 
    } 
    return pixValues; 
} 

EDIT ** Ниже показано, как я хотел бы сделать:

private static unsafe List<PixelF> GetPixels<Timg, Tmask>(
    VMImage img, 
    int band, 
    VMImage imgMask, 
    int bandMask) 
{ 
    List<PixelF> pixValues = new List<PixelF>(); 
    int r, c; 
    int imgSrcOffset = img.LineLength - img.Width; 
    int imgMaskOffset = imgMask.LineLength - imgMask.Width; 
    Timg* pf_imgSrc = (Timg*)img.GetRoiPointer(band); 
    Tmask* pb_imgMask = (Tmask*)imgMask.GetRoiPointer(bandMask); 
    for (r = 0; r < img.Height; r++) // Loop over rows 
    { 
    for (c = 0; c < img.Width; c++) // Loop over columns 
    { 
     if (*pb_imgMask > 0) 
     { 
     pixValues.Add(new PixelF(c, r, (float)*pf_imgSrc)); 
     } 
     ++pf_imgSrc; 
     ++pb_imgMask; 
    } 
    pf_imgSrc += imgSrcOffset; 
    pb_imgMask += imgMaskOffset; 
    } 
    return pixValues; 
} 

Я ожидаю, что я мог бы сделать это в C++ в качестве шаблона, но это возможно в C#

Редактировать ***

Как shambulator указывал, просто пытается сделать

private static unsafe GetPixels_ByteImg_FloatMask<TImg, TMask>(
    VMImage img, 
    int band, 
    VMImage imgMask, 
    int bandMask) 
    where TImg : struct where TMask : struct 
    { 
     TImg* pb_imgSrc = (TImg*)img.GetRoiPointer(band); 
    } 

дает ошибку (не может взять адрес, получить размер или объявить указатель на управляемый тип.)

Edit * * Basicaly, что мне нужно знать размер указатель (байт, короткий, поплавок), и, конечно же, он должен быть корректно отображен с поплавком позже,

+1

Да, примитивные типы могут использоваться как аргументы общего типа. Список , например, является общим. –

+0

Похоже, что когда вы говорите «примитивные типы», вы подразумеваете типы значений. Если да, то в чем проблема? Generics работают как для значений, так и для ссылочных типов (и вы даже можете ограничить общий, где он может быть только одним или другим). –

+0

но, что вы хотите сделать, не является общим. Конечно, общие типы могут быть примитивными типами значений, они могут быть и любым другим типом, если вы не применяете ограничение. – Jodrell

ответ

2

Мое предложение было бы сделать это в отдельной сборке Managed C++, иначе C++/CLI, где публика. NET API предоставляет ваш типизированный интерфейс, а «небезопасный» связанный с указателем материал происходит в собственном коде.

+0

его хорошая идея, я боюсь, что я не могу ее продать в моей компании, так как мы довольно relegius о преобразовании всего в C# вместо C++. Возможно ли иметь эту управляемую оболочку C++ в anyCPU? это было бы хорошей точкой продажи, если это возможно. – buildcomplete

+0

Нет, но вы можете выполнить описанную здесь процедуру http://scottbilas.com/blog/automatically-choose-32-or-64-bit-mixed-mode-dlls/, чтобы автоматически загрузить правильную библиотеку. Я думаю, вы не можете иметь это в обоих направлениях: использование небезопасного указателя и только C# ... –

+0

большое спасибо, я думаю, что это решение. – buildcomplete