2012-11-13 12 views
8

EDIT: Nachdem ich dies unter 32-Bit zu arbeiten, habe ich jetzt versucht, es für 64-Bit zu arbeiten. Ich habe Quellcode für die DLL erhalten und DLL und Anwendung werden für 64-Bit kompiliert. Ich erhalte jedes Mal eine Zugriffsverletzung. Hier ist der DLL-Code (C++ in Visual Studio 2005):Convert Visual Basic 6.0 Typ zu VB.NET 'Struktur'

#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) 

Hinweis es die Packung 2. Einstellung habe ich versucht, es zu 2 in der Anwendung Einstellung als gut, und es funktioniert nicht. Ich habe andere Werte ausprobiert, und ich habe sogar Werte ausprobiert, die nicht gleich waren. Ich habe explizit versucht, 4 als Integer-Größe und 8 als doppelte Größe zu verwenden. Aber ich würde (mit begrenztem Wissen) annehmen, dass, wenn beide Packungsgrößen gleich sind, es funktionieren sollte.

An dieser Stelle vermute ich, wie die Funktion aufgerufen wird. Der erste Parameter ist ein Zeiger auf ein Array dieser Strukturen. Die Anwendung übergibt das erste Element des Arrays ByRef, was ich denke, dass dies erreicht wird. Aber ein schlechter Zeiger auf das Array würde die Symptome erklären. Hier ist die Funktionsdefinition in der DLL.

int WINAPI MNtvaAnalyzeVB (TVA_RESULTS *pResults, int iMaxCount) 

Mein Chef schlug es ein big/little endian Problem sein könnte, aber das scheint unwahrscheinlich, wenn sie beide in der gleichen Umgebung zusammengestellt werden.

Was soll ich tun?

Ende bearbeiten >>>


ich eine Visual Basic 6.0-Anwendung VB.NET bin zu konvertieren. Ich habe ein paar Strukturen, die an externe DLL-Dateien weitergegeben werden. Das funktioniert nicht, und ich habe das Gefühl, dass die Strukturen nicht korrekt weitergeleitet werden.

Hier ist die ursprüngliche Struktur ist:

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 

Wenn ich einen LenB auf einer Variable dieses Typs in Visual Basic 6.0 zu tun, erhalte ich 84 Bytes. (NB: Ich bin nicht sicher, ob das eine gültige Art und Weise um seine Größe zu bestimmen.)

Ich habe versucht, es zu VB.NET konvertieren thusly:

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 

In VB.NET, System.Runtime.InteropServices.Marshal.sizeof() gibt 88 Bytes. Ich hatte gehofft, da dies nur numerische Werte sind, würde das funktionieren (ich weiß, dass Strings ein Schmerz sein können). Ich habe keinen Code für die externe Funktion, aber es wird wie folgt erklärt:

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

ich diese Struktur bin zu raten, ist nicht die gleiche Größe, so dass die DLL-Datei Aufruf fehlschlägt, aber ich habe keine Fehler erhalten, und Wie gesagt, ich habe nicht den Code dafür. Es gibt eine Null zurück, wie es sollte, wenn es erfolgreich ist, aber es hat eindeutig keine Wirkung.

Ich habe ein bisschen mit Runtime.InteropServices.StructLayoutAttribute gespielt, aber wenn das die Antwort ist, kann ich die richtigen Parameter nicht bestimmen.

Ich habe eine andere Struktur wie diese, aber es ist so ähnlich. Ich schätze, wenn ich das Problem beheben kann, kann ich das andere reparieren.

+0

Ich habe keine Ahnung, worum es bei dieser Frage geht, aber es sieht cool aus, also +1. :) – Neolisk

+1

@Neolisk: Es ist wahrscheinlich die "Ich habe ein paar Strukturen, die an externe DLLs übergeben werden. Das funktioniert nicht". –

Antwort

8

Nun natürlich das nächste, was ich versucht habe, das Problem zu beheben. Definieren der Struktur wie folgt:

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

das Problem behoben.

+0

Bedeutet das, dass .net das Double auf eine 8-Byte-Grenze ausgerichtet hat (bevor Sie es behoben haben)? – xpda

+0

@xpda ja, wahrscheinlich – MarkJ

+0

Nun, das ist, was ich dachte, aber die andere Struktur, die ich erwähnt habe, hatte mehrere Long-Variablen und 7 Doubles. Unter .NET, die Longs zu Ganzzahlen ändern, war es nur acht Bytes länger. (Auch hier gilt wieder, dass meine Längenmaße gültig sind.) Also füllte es nicht alle Doppel. Ich bin mir nicht sicher, was genau passierte. Aber es sieht aus wie mit LayoutKind.Sequential und Pack: = 1, es legt nur jede Variable in der aufgeführten Reihenfolge ohne Auffüllung. –

2

Hier sind gute Ressourcen:

Ihre Conversion sieht gut aus, ein long in Visual Basic 6.0 ist 4 Bytes, was 32 Bits ist, was eine Ganzzahl in VB.NET ist. Double sind 8 Bytes sowohl in VB.NET und Visual Basic 6.0 (gemäß den obigen Artikeln). Ich bekomme auch 84 Bytes in VB.NET.

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