none
Marshal Problem with a Big Text structure RRS feed

  • Question

  • Hi!

    I have a Problem with a big TEXT Structure...

    Here is te Problem....

    Imports System.Runtime.InteropServices
    Public Class VBMaxSizeClass
    
        Public WPFSehrLangerText As String
    
    
        <StructLayout(LayoutKind.Sequential)> Public Structure VBSATZ
    
            <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=3000000)> Public SehrLangerText As String
    
        End Structure
    
        Declare Function TESTCALL Lib "COBLangTest.dll" (ByRef VBSATZDATEN As VBSATZ) As Integer
    
        Public Sub TestCall()
    
            Dim CblStatus As Integer
    
            Dim VBSATZ001 = New VBSATZ
    
            VBSATZ001.SehrLangerText = WPFSehrLangerText
    
            CblStatus = TESTCALL(VBSATZ001)
    
            WPFSehrLangerText = VBSATZ001.SehrLangerText.Trim(" ")
    
        End Sub
    
    
    End Class
    

    The SizeConst:=3000000 is to BIG :-(

    But i Need this size as a fix lenght for that i use "ByValTStr"...

    Is there any other way to bring the text down into the SUB DLL?

    Best Regards

    Bernd

    Monday, July 6, 2015 11:52 AM

Answers

  • You are failing here (coreclr sources) so yes, almost 65k limit.

    I was able to work around the parameter marshaling failure by marshaling directly:

            private static void CallViaIntPtr()
            {
                var ts = new TESTSTRUCT();
                ts.TextArray = new StringBuilder(Util.MAX_SIZE_UNI).Append('A', Util.MAX_SIZE_UNI).ToString();
    
                var size = Marshal.SizeOf(ts);
                IntPtr ptr = Marshal.AllocHGlobal(size);
    
                try
                {
                    Marshal.StructureToPtr(ts, ptr, true);
                    var len = TESTCALL2(ptr);
                    Console.WriteLine("The size of the string is 0x{0:X}", len);
                }
                finally
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
    
            private static void CallViaStandardMarshaling()
            {
                var ts = new TESTSTRUCT();
                ts.TextArray = new StringBuilder(Util.MAX_SIZE_UNI).Append('A', Util.MAX_SIZE_UNI).ToString();
                var len = TESTCALL(ref ts);
                Console.WriteLine("The size of the string is 0x{0:X}", len);
            }

    CallViaIntPtr worked fine with 3000000 character Unicode strings (MAX_SIZE_UNI). The largest string that CallViaStandardMarshaling could handle is 0x7ff8 Unicode chars.

    TESTCALL and TESTCALL2 are the same TESTCALL function that just returns the wcslen+1 of TestStruct.TextArray:

            [DllImport("COBLangTest", CallingConvention=CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
            public static extern int TESTCALL(ref TESTSTRUCT ts);
    
            [DllImport("COBLangTest", EntryPoint="TESTCALL", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
            public static extern int TESTCALL2(IntPtr ts);
    Sorry for switching languages on you, I don't think well in VB.NET :)

    Wednesday, July 15, 2015 1:06 AM

All replies

  • Hi Bernd,

    >> The SizeConst:=3000000 is to BIG :-(

    The range of allowed ByValTSTr members is limited to 0x1FFFFFFF, 3000000 is one of allowed value. MarshalAsAttribute.SizeConst Field reference tells more. You should be able to pass it to TestCall method. So what is the problem in your available code? I cannot find anything about COBLangTest.dll, can you post a bit more about your scenario?

    Regards,


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, July 7, 2015 5:17 AM
    Moderator
  • The "COBLangTest.dll"  is a DLL that Need a FIX structur size...

    sometimes it is bigger then 2.000.000 characters...

    For that Problem i Need a solution...

    normaly i become an error that the size is to big for "Marshal"... (Max Size is nearly 65.000...)

    So i Need to findout any other way...

    Best Regards

    Bernd

    Tuesday, July 7, 2015 6:04 AM
  • Hi Bernd,

    I am not very familiar with this "Marshal" problem. Can you provide a repro project which can help troubleshooting or research on it? Use your OneDrive and share a link.

    Thank you.

    Regards,


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Friday, July 10, 2015 5:48 AM
    Moderator
  • You are failing here (coreclr sources) so yes, almost 65k limit.

    I was able to work around the parameter marshaling failure by marshaling directly:

            private static void CallViaIntPtr()
            {
                var ts = new TESTSTRUCT();
                ts.TextArray = new StringBuilder(Util.MAX_SIZE_UNI).Append('A', Util.MAX_SIZE_UNI).ToString();
    
                var size = Marshal.SizeOf(ts);
                IntPtr ptr = Marshal.AllocHGlobal(size);
    
                try
                {
                    Marshal.StructureToPtr(ts, ptr, true);
                    var len = TESTCALL2(ptr);
                    Console.WriteLine("The size of the string is 0x{0:X}", len);
                }
                finally
                {
                    Marshal.FreeHGlobal(ptr);
                }
            }
    
            private static void CallViaStandardMarshaling()
            {
                var ts = new TESTSTRUCT();
                ts.TextArray = new StringBuilder(Util.MAX_SIZE_UNI).Append('A', Util.MAX_SIZE_UNI).ToString();
                var len = TESTCALL(ref ts);
                Console.WriteLine("The size of the string is 0x{0:X}", len);
            }

    CallViaIntPtr worked fine with 3000000 character Unicode strings (MAX_SIZE_UNI). The largest string that CallViaStandardMarshaling could handle is 0x7ff8 Unicode chars.

    TESTCALL and TESTCALL2 are the same TESTCALL function that just returns the wcslen+1 of TestStruct.TextArray:

            [DllImport("COBLangTest", CallingConvention=CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
            public static extern int TESTCALL(ref TESTSTRUCT ts);
    
            [DllImport("COBLangTest", EntryPoint="TESTCALL", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)]
            public static extern int TESTCALL2(IntPtr ts);
    Sorry for switching languages on you, I don't think well in VB.NET :)

    Wednesday, July 15, 2015 1:06 AM