2013-10-31 37 views
3

爲了更好地學習vb.net和C#,我正在嘗試將一個項目(在SourceForge上找到的TreeViewAdv)並嘗試將其代碼轉換爲VB。雖然我希望能夠手動轉換代碼(因爲這是一個學習項目),但我目前正在使用C#到VB代碼轉換器(可在www.DeveloperFusion.com上找到)來獲取球的滾動以及一些基本理解第一。我已經轉換的代碼大部分沒有問題,但有一個問題(也許是2)。見代碼:指針從C#代碼到VB.net存在問題轉換

C#

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Drawing; 
using System.Runtime.InteropServices; 
using System.Drawing.Imaging; 

namespace Aga.Controls 
{ 
public static class BitmapHelper 
{ 
    [StructLayout(LayoutKind.Sequential)] 
    private struct PixelData 
    { 
     public byte B; 
     public byte G; 
     public byte R; 
     public byte A; 
    } 

    public static void SetAlphaChanelValue(Bitmap image, byte value) 
    { 
     if (image == null) 
      throw new ArgumentNullException("image"); 
     if (image.PixelFormat != PixelFormat.Format32bppArgb) 
      throw new ArgumentException("Wrong PixelFormat"); 

     BitmapData bitmapData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height), 
           ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); 
     unsafe 
     { 
      PixelData* pPixel = (PixelData*)bitmapData.Scan0; 
      for (int i = 0; i < bitmapData.Height; i++) 
      { 
       for (int j = 0; j < bitmapData.Width; j++) 
       { 
        pPixel->A = value; 
        pPixel++; 
       } 
       pPixel += bitmapData.Stride - (bitmapData.Width * 4); 
      } 
     } 
     image.UnlockBits(bitmapData); 
    } 
} 
} 

VB.Net(轉換後)

Imports System.Collections.Generic 
Imports System.Text 
Imports System.Drawing 
Imports System.Runtime.InteropServices 
Imports System.Drawing.Imaging 

Namespace Aga.Controls 

Public NotInheritable Class BitmapHelper 

    Private Sub New() 
    End Sub 

    <StructLayout(LayoutKind.Sequential)> _ 
    Private Structure PixelData 
     Public B As Byte 
     Public G As Byte 
     Public R As Byte 
     Public A As Byte 
    End Structure 


    Public Shared Sub SetAlphaChanelValue(ByVal image As Bitmap, ByVal value As Byte) 
     If image Is Nothing Then 
      Throw New ArgumentNullException("image") 
     End If 
     If image.PixelFormat <> PixelFormat.Format32bppArgb Then 
      Throw New ArgumentException("Wrong PixelFormat") 
     End If 

     Dim bitmapData As BitmapData = image.LockBits(New Rectangle(0, 0, image.Width, image.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb) 
     Dim pPixel As Pointer(Of PixelData) = DirectCast(bitmapData.Scan0, Pointer(Of PixelData)) 
     For i As Integer = 0 To bitmapData.Height - 1 
      For j As Integer = 0 To bitmapData.Width - 1 
       pPixel.A = value 
       pPixel += 1 
      Next 
      pPixel += bitmapData.Stride - (bitmapData.Width * 4) 
     Next 
     image.UnlockBits(bitmapData) 
    End Sub 

End Class 

End Namespace 

的問題代碼行,我認爲,主要有: C#

PixelData* pPixel = (PixelData*)bitmapData.Scan0; 

它轉換到這VB

Dim pPixel As Pointer(Of PixelData) = DirectCast(bitmapData.Scan0, Pointer(Of PixelData)) 

智能感知告訴我,有什麼不對的指針(中PixelData取出)

我的問題:什麼是獲得的最好方式上面的VB代碼功能像C#代碼(在結果而不是方法論),爲什麼解決方案的工作原理(我希望理解)?

事情,應該回答或評論時牢記:

1)我已經明白,CRL或託管編程語言不使用指針

2)我不是試圖找到一個在vb.net中使用指針或不安全的代碼的方式我知道這是不能做到的。 3)我不會拋棄VB,也不希望簡單地將C#代碼保存在單獨的程序集中,並從VB中引用它。我明白它有侷限性,但這是一個學習項目,所以當我去面試時他們問我:「你能在VB中做X ?」我可以自信地說是的。

4)再一次,這裏至關重要的不是我採取哪條道路,而是目的地。我知道通過C#有一條通往目的地的較短路線,但我希望通過VB。

獎勵積分,我希望聲明

pPixel + = 1

不要在VB邊工作(如pPixel是一個結構,見上文),但它在建立精細C#方面。爲什麼這個(工作/不工作)在各自的語言。這不是一個關於安全/不安全代碼塊的問題,就像代碼實際運行時一樣,並且不會因爲不適當的投射/類型使用而拋出錯誤(int 1 - > struct pPixel),爲什麼?

+3

C#在包含「不安全」選項的項目中支持「不安全」代碼,包括指針。這不支持在vb ... –

+0

@ReedCopsey。是的,我已經知道了,就像我在問題中所說的那樣。我問的是,「讓代碼工作的最佳方式是什麼?爲什麼?」 – ProtoNoob

+2

只有C#可以使用不安全的代碼。因此,你最好的選擇是拋棄VB.Net並只使用C#。您的第二個最佳選擇是將不安全的代碼保存在C#程序集中,並從VB.Net項目引用該C#程序集。 –

回答

5

在VB.NET中無指針支持,您需要回退到框架支持功能。 Marshal.WriteByte適合票:

Dim pPixel = bitmapData.Scan0 
    For y As Integer = 0 To bitmapData.Height - 1 
     For x As Integer = 0 To bitmapData.Width - 1 
      Marshal.WriteByte(pPixel, 4 * x + 3, value) 
     Next 
     pPixel += bitmapData.Stride 
    Next 

當然,從來沒有拋棄.NET支持的優秀語言interop。 VB.NET程序可以非常容易地使用C#類庫項目。

+0

非常感謝,(雖然在確認之前我有一些工作要做)。不過,我確實有一個問題。爲什麼「4 * x + 3」中的+3?在我們正在處理的對象的性質中是否存在某種需要這種偏移量的數據,或者只是說明性的數字? – ProtoNoob

+1

這是因爲alpha字節在32位像素的偏移量3處。就像你的PixelData結構所說:offset 0 =藍色,1 =綠色,2 =紅色,3 = alpha。 VB.NET程序員必須更好地瞭解機器:) –

1

不幸的是,VB。Net不支持通過指針直接處理數據。與C#相比,這是VB的一個顯着缺點 - 當你需要它時不能訪問不安全的代碼。

在這種情況下,圍繞它的方法實際上是從IntPtr複製到一個字節數組,執行操作,然後複製回來。這可以通過Marshal.Copy方法完成。

Bitmap.LockBits MSDN上的示例代碼VB顯示了整個過程,以及如何操作VB中的位圖像素數據。