2012-11-13 210 views
8

编辑:已经得到这个在32位下工作,我现在试图让它为64位工作。我已经获得了DLL的源代码,并且正在为64位编译DLL和应用程序。我每次都会遇到访问冲突。这里是DLL的代码(C++中Visual Studio 2005):将Visual Basic 6.0类型转换为VB.NET'Structure'

#pragma pack(push, 2) 
// Output Results Structure 
typedef struct tagTVA_RESULTS { 
    int iID;    /* Difference ID 1 .. n */ 
    int iLeft;   /* Bounding rectangle */ 
    int iRight; 
    int iTop; 
    int iBottom; 
    double dCx;   /* Center of gravity */ 
    double dCy; 
    double dMajor;   /* Shape information */ 
    double dMinor; 
    double dAngle;   /* Rotational information */ 
    int lArea;   /* Number of pixels */ 
    int iEdge;   /* Set if difference is at the edge of the image */ 
    double dNormalDensity; 
    int iNormalCount; 
    double dDifferenceDensity; 
} TVA_RESULTS, *PTVA_RESULTS; 
#pragma pack (pop) 

注意它的包设置为2。我试图在应用程序将其设置为2,以及,它失败。我尝试了其他值,甚至尝试了不同的值。我已经尝试明确使用4作为整数大小和8作为双倍大小。但我会假设(有限的知识),如果两个包装大小是相同的,它应该工作。

在这一点上,我怀疑如何调用该函数。它的第一个参数是一个指向这些结构数组的指针。应用程序传入数组ByRef的第一个元素,我认为这可以实现这一点。但是如果指向数组的指针可能会解释这些症状。这是DLL中的函数定义。

int WINAPI MNtvaAnalyzeVB (TVA_RESULTS *pResults, int iMaxCount) 

我的老板认为它可能是一个big/little endian的问题,但似乎不太可能,如果他们都被在同一环境中编译。

我该怎么办?编辑

末>>>


我转换的Visual Basic 6.0应用程序到VB.NET。我有几个结构传递给外部DLL文件。这不起作用,我有一种感觉,这是由于结构没有正确传递。

这里的原始结构:

Public Type TVA_PARAMETERS 
    iStandardFilterOnOff As Long 
    iSampleFilterOnOff As Long 
    iDifferenceFilterOnOff As Long 
    iRotationCorrectionOnOff As Long 
    iLocalCorrectionOnOff As Long 
    iStandardAOIx As Long 
    iStandardAOIy As Long 
    iStandardAOIdx As Long 
    iStandardAOIdy As Long 
    iSampleAOIx As Long 
    iSampleAOIy As Long 
    iSampleAOIdx As Long 
    iSampleAOIdy As Long 
    iRepeatHorizontal As Long 
    iRepeatVertical As Long 
    dSensitivity As Double 
    iMergeWidth As Long 
    iMergeHeight As Long 
    iMinimumDifferenceArea As Long 
    iMaximumDifferenceArea As Long 
End Type 

如果我做了LENB该类型的Visual Basic 6.0中的变量,我得到84个字节。 (注:我不知道,如果这对确定其大小的一种有效方式。)

我曾试图把它正是如此转换到VB.NET:

Public Structure TVA_PARAMETERS 
    Public iStandardFilterOnOff As Integer 
    Public iSampleFilterOnOff As Integer 
    Public iDifferenceFilterOnOff As Integer 
    Public iRotationCorrectionOnOff As Integer 
    Public iLocalCorrectionOnOff As Integer 
    Public iStandardAOIx As Integer 
    Public iStandardAOIy As Integer 
    Public iStandardAOIdx As Integer 
    Public iStandardAOIdy As Integer 
    Public iSampleAOIx As Integer 
    Public iSampleAOIy As Integer 
    Public iSampleAOIdx As Integer 
    Public iSampleAOIdy As Integer 
    Public iRepeatHorizontal As Integer 
    Public iRepeatVertical As Integer 
    Public dSensitivity As Double 
    Public iMergeWidth As Integer 
    Public iMergeHeight As Integer 
    Public iMinimumDifferenceArea As Integer 
    Public iMaximumDifferenceArea As Integer 
End Structure 

在VB.NET,System.Runtime.InteropServices.Marshal.sizeof()给88字节。我希望,因为这些只是数值,这将工作(我知道字符串可以是一个痛苦)。我没有对外部函数的代码,但它的声明如下:

Declare Function MNtvaParameters Lib "MNTva.dll" (ByRef pParameters As TVA_PARAMETERS) As Integer 

我猜这种结构是不一样的大小,这样的DLL文件调用失败,但我没有得到任何错误,并正如我所说,我没有看代码的代码。它返回一个零,如果它是成功的,但它显然没有实际效果。

我玩过Runtime.InteropServices.StructLayoutAttribute,但如果这是答案,我无法确定正确的参数。

我有另一个这样的结构,但它是如此相似。我猜如果我能解决这个问题,我可以解决其他问题。

+0

我不知道这个问题是关于什么的,但它看起来很酷,所以+1。 :) – Neolisk

+1

@Neilisk:它可能是“我有一些结构传递给外部DLL,这不起作用”。 –

回答

8

当然,我试图解决问题的下一件事。定义这样的结构:

<Runtime.InteropServices.StructLayout(Runtime.InteropServices.LayoutKind.Sequential, Pack:=1)> _ 
Public Structure TVA_PARAMETERS 
    Public iStandardFilterOnOff As Integer 
    ... 
    etc. 

修复了这个问题。

+0

这是否意味着.net将double与8字节边界对齐(在修复之前)? – xpda

+0

@xpda是的,可能 – MarkJ

+0

那么这就是我的想法,但我提到的其他结构有几个长变量和7个双打。在.NET下,将Longs更改为Integers,它只有八个字节。 (再次假设我的长度测量是有效的。)所以它不是填充所有双打。我不确定到底发生了什么。 但它看起来像使用LayoutKind.Sequential和Pack:= 1,它只是按列出的顺序放置每个变量而没有填充。 –

2

这里有很好的资源:

你转换看起来不错,在Visual Basic 6.0 long是4个字节,它是32位,它是VB.NET中的一个整数。在VB.NET和Visual Basic 6.0中,双精度都是8个字节(根据上述文章)。我也在VB.NET中获得了84个字节。

Option Strict On 

Public Class Form1 

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
     Dim A As New TVA_PARAMETERS 
     MsgBox(A.ByteCount.ToString) 
    End Sub 

    Public Structure TVA_PARAMETERS 
     Public iStandardFilterOnOff As Int32 
     Public iSampleFilterOnOff As Int32 
     Public iDifferenceFilterOnOff As Int32 
     Public iRotationCorrectionOnOff As Int32 
     Public iLocalCorrectionOnOff As Int32 
     Public iStandardAOIx As Int32 
     Public iStandardAOIy As Int32 
     Public iStandardAOIdx As Int32 
     Public iStandardAOIdy As Int32 
     Public iSampleAOIx As Int32 
     Public iSampleAOIy As Int32 
     Public iSampleAOIdx As Int32 
     Public iSampleAOIdy As Int32 
     Public iRepeatHorizontal As Int32 
     Public iRepeatVertical As Int32 
     Public dSensitivity As Double 
     Public iMergeWidth As Int32 
     Public iMergeHeight As Int32 
     Public iMinimumDifferenceArea As Int32 
     Public iMaximumDifferenceArea As Int32 

     Function ByteCount() As Integer 
      Dim Results As New List(Of Byte) 
      AddBytesToList(Results, BitConverter.GetBytes(iStandardFilterOnOff)) 
      AddBytesToList(Results, BitConverter.GetBytes(iSampleFilterOnOff)) 
      AddBytesToList(Results, BitConverter.GetBytes(iDifferenceFilterOnOff)) 
      AddBytesToList(Results, BitConverter.GetBytes(iRotationCorrectionOnOff)) 
      AddBytesToList(Results, BitConverter.GetBytes(iLocalCorrectionOnOff)) 
      AddBytesToList(Results, BitConverter.GetBytes(iStandardAOIx)) 
      AddBytesToList(Results, BitConverter.GetBytes(iStandardAOIy)) 
      AddBytesToList(Results, BitConverter.GetBytes(iStandardAOIdx)) 
      AddBytesToList(Results, BitConverter.GetBytes(iStandardAOIdy)) 
      AddBytesToList(Results, BitConverter.GetBytes(iSampleAOIx)) 
      AddBytesToList(Results, BitConverter.GetBytes(iSampleAOIy)) 
      AddBytesToList(Results, BitConverter.GetBytes(iSampleAOIdx)) 
      AddBytesToList(Results, BitConverter.GetBytes(iSampleAOIdy)) 
      AddBytesToList(Results, BitConverter.GetBytes(iRepeatHorizontal)) 
      AddBytesToList(Results, BitConverter.GetBytes(iRepeatVertical)) 
      AddBytesToList(Results, BitConverter.GetBytes(dSensitivity)) 
      AddBytesToList(Results, BitConverter.GetBytes(iMergeWidth)) 
      AddBytesToList(Results, BitConverter.GetBytes(iMergeHeight)) 
      AddBytesToList(Results, BitConverter.GetBytes(iMinimumDifferenceArea)) 
      AddBytesToList(Results, BitConverter.GetBytes(iMaximumDifferenceArea)) 
      Return Results.Count 
     End Function 

     Sub AddBytesToList(ByRef List As List(Of Byte), addBytes As Byte()) 
      For Each B As Byte In addBytes 
       List.Add(B) 
      Next 

     End Sub 
    End Structure 

End Class