2013-03-21 39 views
0

這是我的問題:如何循環通過C#中的IntPtr指向的東西? 我有C#代碼調用C++代碼。 C++代碼返回一個指向一塊圖像緩衝區的指針。 C#和C之間的接口++是在C#中聲明一個IntPtr變量 因此,這裏是我的C#代碼:循環IntPtr?

private IntPtr _maskData; 

public void LoadMask(string maskName) 
{    
    _maskData = Marshal.AllocHGlobal(_imgWidth * _imgHeight * 1); 
    ReadImage(maskName, ref _maskData); 
} 

[DllImport(@"D:\Projects\ImageStatistics\ImageStatisticsEllipse\Debug\DiskIO.dll", EntryPoint = "ReadImage")] 
     private static extern int ReadImage([MarshalAs(UnmanagedType.LPWStr)]string path, ref IntPtr outputBuffer); 

這裏是我的C++代碼:

DllExport_ThorDiskIO ReadImage(char *selectedFileName, char* &outputBuffer) 
{ 
    TIFF* image; 
    tsize_t stripSize; 
    unsigned long imageOffset, result; 
    int stripMax, stripCount; 
    unsigned long bufferSize; 
    wchar_t * path = (wchar_t*)selectedFileName; 
    bool status; 

    // Open the TIFF image 
    if((image = tiffDll->TIFFOpenW(path, "r")) == NULL){ 
     //  logDll->TLTraceEvent(VERBOSE_EVENT,1,L"Could not open incoming image"); 

    } 

    // Read in the possibly multiple strips 
    stripSize = tiffDll->TIFFStripSize(image); 
    stripMax = tiffDll->TIFFNumberOfStrips (image); 
    imageOffset = 0; 

    bufferSize = tiffDll->TIFFNumberOfStrips (image) * stripSize; 

    for (stripCount = 0; stripCount < stripMax; stripCount++) 
    { 
     if((result = tiffDll->TIFFReadEncodedStrip (image, stripCount, outputBuffer + imageOffset, stripSize)) == -1) 
     { 
      //logDll->TLTraceEvent(VERBOSE_EVENT,1,L"Read error on input strip number"); 
     } 
     imageOffset += result; 
    } 

    // Close the TIFF image 
    tiffDll->TIFFClose(image); 

    if(outputBuffer > 0) 
    { 
     //logDll->TLTraceEvent(VERBOSE_EVENT,1,L"inside output buffer: TRUE"); 
     status = TRUE; 
    } 
    else 
    { 
     //logDll->TLTraceEvent(VERBOSE_EVENT,1,L"inside output buffer: FALSE"); 
     status = FALSE; 
    } 
    return status; 
} 

所以現在我想我可以得到IntPtr成功,但問題實際上是:我如何使用它?我如何通過在圖像緩衝區中的每個像素的循環,像(僞代碼):

for (int y = 0; y < imgHeight; y++) 
    for (int x = 0; x < imgWidth; x++) 
    { 
     int pixVal = IntPtr[y * imgWidth + x ]; 

     // do something to process the pixel value here.... 

    } 
+0

一個'IntPtr'不是一個緩衝區,它是一個內存地址(在這種情況下,指向一個緩衝區的開始)。你不能「循環」一個內存地址。但是,您可以使用不安全的代碼通過指針算術在不安全的指針上循環緩衝區。 – 2013-03-21 14:53:20

+0

['Marshal.PtrToStructure'](http://msdn.microsoft.com/en-us/library/4ca6d5z7.aspx) – Romoku 2013-03-21 14:53:23

+0

@Romoku:如果我有一塊char *的緩衝區?或者一個字節*?一般來說8位數據結構?似乎IntPtr只有.ToInt32()和.ToInt64(),似乎我不能從我的緩衝區正確檢索我的價值。 – 2013-03-21 15:42:46

回答

2

這是如何循環的圖像指出使用一個IntPtr(指向本機內存)

//assume this actually points to something (not zero!!) 
IntPtr pNative = IntPtr.Zero; 

//assume these are you image dimensions 
int w=640; //width 
int h=480; //height 
int ch =3; //channels 

//image loop 
//use unsafe 
//this is very fast!! 
unsafe 
{ 
    for (int r = 0; r < h; r++) 
    { 
     byte* pI = (byte*)pNative.ToPointer() + r*w*ch; //pointer to start of row 
     for (int c = 0; c < w; c++) 
     { 
      pI[c * ch]  = 0; //red 
      pI[c * ch+1] = 0; //green 
      pI[c * ch+2] = 0; //blue 

//also equivalent to *(pI + c*ch) = 0 - i.e. using pointer arythmetic; 
     } 
    } 
}