C# C结构到VB6,反之亦然

C# C结构到VB6,反之亦然,c#,vb6,marshalling,C#,Vb6,Marshalling,我试图从C结构转储数据,然后将数据加载到VB6结构。 这是当前代码: C 使用制度; 使用System.Collections.Generic; 使用系统组件模型; 使用系统数据; 使用系统图; 使用System.Linq; 使用系统文本; 使用System.Windows.Forms; 使用System.Runtime.InteropServices; 使用System.IO; 命名空间封送处理测试 { 公共部分类Form1:Form { 公共表格1 { 初始化组件; } [StructLay

我试图从C结构转储数据,然后将数据加载到VB6结构。 这是当前代码: C

使用制度; 使用System.Collections.Generic; 使用系统组件模型; 使用系统数据; 使用系统图; 使用System.Linq; 使用系统文本; 使用System.Windows.Forms; 使用System.Runtime.InteropServices; 使用System.IO; 命名空间封送处理测试 { 公共部分类Form1:Form { 公共表格1 { 初始化组件; } [StructLayoutKind.Sequential,CharSet=CharSet.Ansi] 公共结构myStruct { [MarshalAsUnmanagedType.ByValTStr,SizeConst=5] 公共字符串str; [MarshalAsUnmanagedType.I4] public int integer;//VB6 long [MarshalAsUnmanagedType.I2] 公共Int16 Int16;//VB6整数 [MarshalAsUnmanagedType.I1] 公共字节b; [MarshalAsUnmanagedType.VariantBool] 公共布尔旗; } 私有无效按钮1\u单击对象发送者,事件参数e { myStruct strc=新myStruct; //String.Format{0,6},strc.str; strc.str=Abhi; strc.integer=49125071; strc.int16=0491; strc.b=4; strc.flag=true; 类型outputType=typeofmyStruct.IsEnum?Enum.GetUnderlineingTypeOfMystruct:typeofmyStruct; byte[]bArr=新字节[Marshal.SizeOfstrc]; IntPtr ptr=IntPtr.0; 尝试 { ptr=Marshal.allochlobalmarshal.SizeOfstrc; Marshal.StructureToPtrstrc,ptr,false; Marshal.Copyptr,bArr,0,Marshal.SizeOfstrc; 使用FileStream fs=File.CreateC:\\users\\abhijeet\\desktop\\data.dat { fs.WritebArr,0,bArr.Length; 财政司司长:结束; } //WM_应用程序是0x8000 //IntPtr retval=SendMessagem_HostWindow,0x8000,IntPtr.Zero,ptr; } 最后 { 如果ptr!=IntPtr.Zero { Marshal.DestroyStructureptr,系统结构的类型; 弗里赫格罗巴普特元帅; } } } 私有字符串checkedFixedLength字符串str,int-length { 如果str.Length>Length { 返回str.Substring0,长度; } 返回str; } } } VB6

选项显式 'Private声明Sub CopyMemory Lib kernel32别名rtlmovemory Destination为Any,Source为Any,ByVal ByteLen为Long 私有声明函数GetProcessHeap Lib kernel32的长度为 私有声明函数HeapAlloc Lib kernel32 ByVal hHeap为Long,ByVal dwFlags为Long,ByVal dwBytes为Long 私有声明函数HeapFree Lib kernel32 ByVal hHeap为Long,ByVal dwFlags为Long,lpMem为Any为Long Private将Sub-CopyMemory Lib kernel32别名rtlmovemory Destination声明为Any,Source声明为Any,ByVal长度声明为Long str作为字符串 我只要 i作为整数 b作为字节 标记为布尔值 端型

Private Sub cmdCommand1_Click()
    Dim t As myType, f As Long
    Dim bArr() As Byte

    Debug.Print LenB(t)

    ReDim bArr(LenB(t) - 1)
    f = FreeFile
    Open "c:\users\abhijeet\desktop\data.dat" For Binary As #f
    Get #f, , bArr()
    Close #f

    Dim ptr As Long, hHeap As Long
    hHeap = GetProcessHeap
    ptr = HeapAlloc(hHeap, 0, LenB(t))

    CopyMemory ByVal VarPtr(t), ByVal VarPtr(bArr(0)), LenB(t)

    Debug.Print t.str
    Debug.Print t.l
    Debug.Print t.i
    Debug.Print t.b
    Debug.Print t.flag
End Sub
由于某些原因,即使设置了大小常量,结构的大小始终返回16。我是不是在结构上遗漏了什么


谢谢

结构大小不会包含字符串内容,除非它是固定大小而不是指针

[MarshalAs(UnmanagedType.ByValTStr, SizeConst=6)]
public string str;
请注意,说明它与带有空终止符的Vb6不同

在VB6端,您还需要将其设置为固定长度的字符串,以包含内联内容

str As String * 6

结构大小不包括字符串内容,除非它是固定大小而不是指针

[MarshalAs(UnmanagedType.ByValTStr, SizeConst=6)]
public string str;
请注意,说明它与带有空终止符的Vb6不同

在VB6端,您还需要将其设置为固定长度的字符串,以包含内联内容

str As String * 6

这是一些严重的低级代码!为什么不使用VB6本机文件I/O支持,然后在C中添加对Microsoft.VisualBasic的引用,并使用FileOpen、FileGet、FilePut等。?这些.Net功能允许文件与VB6程序的互操作性。例如,虽然我同意@MarkJ,但如果你想使用任何其他形式的IPC,这并不总是可行的。我使用C文件I/O的唯一原因是出于测试目的。这是一些严重的低级代码!为什么不使用VB6本机文件I/O支持,然后在C中添加对Microsoft.VisualBasic的引用,并使用FileOpen、FileGet、FilePut等。?这些.Net功能允许文件与VB6程序的互操作性。例如,虽然我同意@MarkJ,但如果您想使用任何其他形式的IPC,这并不总是可行的。我使用C的文件I/O的唯一原因是出于测试目的。我尝试了它,大小增加了,但由于某种原因,C中的结构大小与
VB6 x 4bytes.VB6在2字节边界上打包,但有些例外情况我不记得了。据我所知,这个结构总共应该是18个字节,6,4,2,1+1,4。一个4的包将产生22个字节6,4,2+2,1+3,4。这个包不会导致字节的变化。它的大小是多少?写入数据文件的原始数据是什么?我做了一些测试。我将编辑上面的代码。现在大小对齐,但问题是VB6端的字符串读取不正确!我试过了,大小增加了,但由于某种原因,C中结构的大小与VB6的大小相差4字节。VB6以2字节边界打包,但有些例外情况我记不起来了。据我所知,这个结构总共应该是18个字节,6,4,2,1+1,4。一个4的包将产生22个字节6,4,2+2,1+3,4。这个包不会导致字节的变化。它的大小是多少?写入数据文件的原始数据是什么?我做了一些测试。我将编辑上面的代码。现在大小对齐,但问题是VB6端的字符串读取不正确!