4

もともとvb6で書かれたアプリケーションをvb.netに変換しています。このアプリケーションが行うことの1つは、「Type」オブジェクトをdllに送信することです。タイプを構造に変換してdllをp/呼び出ししようとしましたが、機能しないようです。私は一週間立ち往生していますどんな助けでも本当にありがたいです

これがタイプのvb6コードです

'Define WICS Communications Control Block (CCB).
Type WicsCCBType ' Create user-defined type.
    CCBNum As String * 1
    CCBVer As String * 1
    Resp1  As String * 4
    Resp2  As String * 4
    PLUA   As String * 8
    LLUA   As String * 8
    Mode   As String * 8
    ReqMax As String * 5
    ResMax As String * 5
End Type      

これがdllの呼び出し方法です

Private Declare Sub WICSRASP Lib "wicsrasp.dll" (MyWicsCCB As WicsCCBType)
WICSRASP MyWicsCCB

これは私がvb.netで試したものですが、機能していません

'Define WICS Communications Control Block (CCB).
    <System.Runtime.InteropServices.StructLayoutAttribute( _
            System.Runtime.InteropServices.LayoutKind.Sequential, _
            CharSet:=System.Runtime.InteropServices.CharSet.[Unicode])> _
    Structure WicsCCBType ' Create user-defined type.
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=1)> Dim CCBNum As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=1)> Dim CCBVer As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=4)> Dim Resp1 As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=4)> Dim Resp2 As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=8)> Dim PLUA As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=8)> Dim LLUA As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=8)> Dim Mode As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=5)> Dim ReqMax As String
        <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=5)> Dim ResMax As String
    End Structure

そしてここが私がそれを呼ぼうとしたところです

<System.Runtime.InteropServices.DllImportAttribute("C:\windows\system32\wicsrasp.dll")> _
    Public Shared Sub WICSRASP(
                    ByRef CCB As WicsCCBType,
                    ByRef Request As DAWicsRequestType,
                    ByRef Response As DAWicsResponseType)
    End Sub

 Dim CCB As New modWICSDiary.WicsCCBType()
 CCB.CCBNum = "B"
            CCB.CCBVer = "2"
            CCB.LLUA = "        "
            CCB.Mode = "CICSMO2 "
            CCB.ReqMax = "2100 "
            CCB.ResMax = "2100 "
            CCB.Resp1 = "0   "
            CCB.Resp2 = "0   "
            CCB.PLUA = "WICSPLU "

  NativeMethods.WICSRASP(CCB)

値に関しては、同じ値がvb6タイプで機能します

よろしくお願いします

4

3 に答える 3

1

これがOPによってまだ解決されているかどうかはわかりませんが、これが私の見解です。

VB6 の UDT 内の固定長文字列は、ポインターとしてマーシャリングされず、構造体にインライン化されます。さらに、VB6 はマーシャリングの前に Unicode を Ansi に変換します。また、VB6 は 4 バイト アラインメントを使用します。

型はメモリ内でパディングを使用してこれを参照します。連続する各フィールドは、図では A から I までの名前が付けられており、_ は位置合わせによるパッド バイトです。

CCBNum As String * 1     
|
|+-CCBVer As String * 1     
||
||  Resp1  As String * 4
||  |
||  |   Resp2  As String * 4     
||  |   |
||  |   |   PLUA   As String * 8     
||  |   |   |
||  |   |   |       LLUA   As String * 8     
||  |   |   |       |
||  |   |   |       |       Mode   As String * 8     
||  |   |   |       |       |
||  |   |   |       |       |       ReqMax As String * 5     
||  |   |   |       |       |       |
||  |   |   |       |       |       |       ResMax As String * 5 
||  |   |   |       |       |       |       |
||  |   |   |       |       |       |       |
VV  V   V   V       V       V       V       V

AB__CCCCDDDDEEEEEEEEFFFFFFFFGGGGGGGGHHHHH___IIIII___

したがって、CharSet は Ansi、StructAlignment は 4 である必要があります。ByValTString の使用は、SizeConst の使用と同様に問題ありません。

于 2012-06-19T12:57:43.643 に答える
1

VB6 は、これらすべての文字列要素を ANSI 文字列として「マーシャリング」します。それに応じて Vb.Net マーシャリング コードを変更します。

  • UnmanagedType.LPStrそれらのMarshalAs属性を試しますか?
  • CharSet を Unicode から Ansi に変更してみてください。
  • で試してみてPack=4くださいStructLayoutAttribute

VB6 による仮定を説明する便利なリンクDeclare

于 2012-05-31T17:04:57.950 に答える
0

VB6 は BSTR を使用していましたね。BSTR としてマーシャリングするべきではありませんか?

于 2012-06-01T07:27:21.897 に答える