2012-11-13 168 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