2012-11-13 38 views
8

CHỈNH SỬA: Đã làm việc này dưới 32 bit, tôi hiện đang cố gắng làm cho nó hoạt động với 64 bit. Tôi đã nhận được mã nguồn cho DLL và cả hai DLL và ứng dụng đang được biên dịch cho 64-bit. Tôi bị vi phạm quyền truy cập mỗi lần. Đây là mã DLL (C++ trong Visual Studio 2005):Chuyển đổi loại Visual Basic 6.0 sang VB.NET 'Cấu trúc'

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

Lưu ý nó thiết lập các gói để 2. Tôi đã thử đặt nó đến 2 trong ứng dụng là tốt, và nó không thành công. Tôi đã thử các giá trị khác và thậm chí tôi đã thử các giá trị không giống nhau. Tôi đã thử rõ ràng bằng cách sử dụng 4 như kích thước nguyên và 8 là kích thước gấp đôi. Nhưng tôi sẽ giả định (với kiến ​​thức hạn chế) rằng nếu cả hai kích thước gói đều giống nhau, nó sẽ hoạt động.

Tại thời điểm này, tôi nghi ngờ cách hàm được gọi. Tham số đầu tiên của nó là một con trỏ tới một mảng của các cấu trúc này. Ứng dụng này chuyển qua phần tử đầu tiên của mảng ByRef, mà tôi nghĩ là hoàn thành điều này. Nhưng có một con trỏ xấu đến mảng sẽ giải thích các triệu chứng. Đây là định nghĩa hàm trong DLL.

int WINAPI MNtvaAnalyzeVB (TVA_RESULTS *pResults, int iMaxCount) 

Sếp của tôi cho rằng đây có thể là vấn đề big/little endian, nhưng dường như chúng không được biên soạn trong cùng một môi trường.

Tôi nên làm gì?

Kết thúc chỉnh sửa >>>


Tôi đang chuyển đổi một ứng dụng Visual Basic 6.0 để VB.NET. Tôi có một vài cấu trúc được chuyển tới các tệp DLL bên ngoài. Điều này không hiệu quả, và tôi có cảm giác đó là do các cấu trúc không được truyền chính xác.

Dưới đây là cấu trúc ban đầu:

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 

Nếu tôi làm một LenB vào một biến kiểu đó trong Visual Basic 6.0, tôi nhận được 84 byte. (NB: Tôi không chắc chắn nếu đó là một cách hợp lệ để xác định kích thước của nó.)

Tôi đã cố gắng để chuyển nó sang VB.NET 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 

Trong VB.NET, System.Runtime.InteropServices.Marshal.sizeof() cho 88 byte. Tôi đã hy vọng vì đây chỉ là giá trị số này sẽ làm việc (tôi biết dây có thể là một nỗi đau). Tôi không có mã cho chức năng bên ngoài, nhưng nó tuyên bố như thế này:

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

Tôi đoán cấu trúc này không phải là kích thước tương tự, vì vậy cuộc gọi tập tin DLL bị lỗi, nhưng tôi nhận được không có lỗi, và như tôi đã nói, tôi không có mã để xem nó. Nó trả về một số không, như là nếu nó thành công, nhưng rõ ràng là nó không thực sự có hiệu lực.

Tôi đã chơi xung quanh một chút với Runtime.InteropServices.StructLayoutAttribute, nhưng nếu đó là câu trả lời, tôi không thể xác định đúng thông số.

Tôi có một cấu trúc như thế này, nhưng nó rất giống nhau. Tôi đoán nếu tôi có thể sửa cái này, tôi sẽ có thể sửa cái kia.

+0

Tôi không biết câu hỏi này là gì, nhưng có vẻ thú vị, vì vậy +1. :) – Neolisk

+1

@Neolisk: Có lẽ là "Tôi có một vài cấu trúc được chuyển tới các tệp DLL bên ngoài. Điều này không hoạt động". –

Trả lời

8

Tất nhiên điều tiếp theo tôi đã cố khắc phục sự cố. Xác định cấu trúc như sau:

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

khắc phục sự cố.

+0

Điều đó có nghĩa là .net căn chỉnh đôi với ranh giới 8 byte (trước khi bạn sửa nó)? – xpda

+0

@xpda yes, có lẽ là – MarkJ

+0

Đó là những gì tôi nghĩ, nhưng Cấu trúc khác mà tôi đã đề cập có một vài biến Long và 7 Doubles. Trong .NET, thay đổi Longs thành Integers, nó chỉ dài hơn 8 byte. (Một lần nữa, giả định các phép đo chiều dài của tôi là hợp lệ.) Vì vậy, nó không phải đệm tất cả các đôi. Tôi không chắc điều gì đã xảy ra chính xác. Nhưng có vẻ như với LayoutKind.Sequential và Pack: = 1, nó chỉ đặt mỗi biến trong thứ tự được liệt kê mà không có đệm. –

2

Dưới đây là nguồn lực tốt:

chuyển đổi của bạn có vẻ tốt, một long trong Visual Basic 6.0 là 4 byte là 32 bit, là một số nguyên trong VB.NET. Đôi là 8 byte cả trong VB.NET và Visual Basic 6.0 (theo các bài viết trên). Tôi cũng nhận được 84 byte trong 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 
Các vấn đề liên quan