2013-10-31 36 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中的位图像素数据。