Sign in to follow this  
Followers 0
kennyl

DllStructSetData truncates the value in char[] type

14 posts in this topic

#1 ·  Posted (edited)

Here's the example script:

$String = "A中文字符串A" ; An unicode string contains multibyte chars

$nAnsiBufferSize = (StringLen($String)+1) * 2; Large enough to store the ansi string

$pAnsiString = DllStructCreate("char[" & $nAnsiBufferSize & "]")

DllStructSetData($pAnsiString, 1, $String)

MsgBox(0, "String is", "[" & DllStructGetData($pAnsiString, 1) & "]" )

In the message box, you can see that the string was truncated. Maybe this is a bug?

Best regards!

Edited by kennyl

Share this post


Link to post
Share on other sites



Here's the example script:

$String = "A中文字符串A"; An unicode string contains multibyte chars

$nAnsiBufferSize = (StringLen($String)+1) * 2; Large enough to store the ansi string

$pAnsiString = DllStructCreate("char[" & $nAnsiBufferSize & "]")

DllStructSetData($pAnsiString, 1, $String)

MsgBox(0, "String is", "[" & DllStructGetData($pAnsiString, 1) & "]" )

In the message box, you can see that the string was truncated. Maybe this is a bug?

Best regards!

Does it work if you use wchar instead of char in your DllStructCreate?

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

@kennyl

How do you write chinese symbols in SciTE ?

Because It write : "A?????A"

$String = "A?????A" ; An unicode string contains multibyte chars

$nAnsiBufferSize = (StringLen($String) + 1) * 2; Large enough to store the ansi string
ConsoleWrite("nAnsiBufferSize : " & $nAnsiBufferSize & @CRLF)

$pAnsiString = DllStructCreate("char[" & $nAnsiBufferSize & "]")
ConsoleWrite("pAnsiString : " & $nAnsiBufferSize & @CRLF)

DllStructSetData($pAnsiString, 1, $String)
ConsoleWrite("pAnsiString : " & $nAnsiBufferSize & @CRLF)

MsgBox(0, "String Result", "[" & DllStructGetData($pAnsiString, 1) & "]")
Edited by FireFox

 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Does it work if you use wchar instead of char in your DllStructCreate?

Of course it works if we use wchar, but my point is DllStructSetData truncates char[] in the case that I have to use char[].

@kennyl

How do you write chinese symbols in SciTE ?

Because It write : "A?????A"

1) I type chinese chars using Input Method applications.

2) In fact, if you can copy some Japanese/Korean/etc... chars and replace the string in my script, the problem will still exist.

3) If you cannot copy those multibyte chars, maybe we can construct one in hex mode:

the string shows in "A?????A" is actually:

00000000h: 41 D6 D0 CE C4 D7 D6 B7 FB B4 AE 41 00         ; A中文字符串A

Thanks for your kindly reply.

Edited by kennyl

Share this post


Link to post
Share on other sites

Currently, the only way is set the data(array) element one by one.

I hope this BUG can be fixed ASAP.

Share this post


Link to post
Share on other sites

Currently, the only way is set the data(array) element one by one.

I hope this BUG can be fixed ASAP.

What the AutoIt version you are using? Because:

3.3.0.0 (24th December, 2008) (Release)

- Fixed #92: DllStruct data truncated with char[]/wchar[].

Share this post


Link to post
Share on other sites

What the AutoIt version you are using? Because:

24th December, 2008 - v3.3.0.0

Obviously, the bug was not fixed.

Share this post


Link to post
Share on other sites

Does it work, if you use StringToBinary first?


*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites

Currently, the only way is set the data(array) element one by one.

I hope this BUG can be fixed ASAP.

See, here's the thing. You aren't proving there's a bug. My guess is that there's an embedded NULL in the DllStruct and thus the string is displayed only up until that point. Look at the binary representation or a character-by-character representation of the contents of the structure. I bet you're going to find it's all there and that it's stored with some NULL's in there.

As for the truncation bug fixed in the release, it's unrelated.

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Does it work, if you use StringToBinary first?

Unfortunately NO, the string will still be truncated.

See, here's the thing. You aren't proving there's a bug. My guess is that there's an embedded NULL in the DllStruct and thus the string is displayed only up until that point. Look at the binary representation or a character-by-character representation of the contents of the structure. I bet you're going to find it's all there and that it's stored with some NULL's in there.

As for the truncation bug fixed in the release, it's unrelated.

But why the NULL was embedded in the DllStruct while the string itself does not contain NULL(except the terminate NULL)?

I first use these following codes to get an Ansi string and try to put it into a DllStruct:

#Include <WinAPI.au3>

$szUnicodeString = "A中文字符串A"
$pUnicodeStringStruct = DllStructCreate("wchar[" & StringLen($szUnicodeString)+1 & "]")
DllStructSetData($pUnicodeStringStruct, 1, $szUnicodeString)

$nAnsiBufferSize = (StringLen($szUnicodeString)+1) * 2
$pAnsiStringStruct = DllStructCreate("char[" & $nAnsiBufferSize & "]")

$szAnsiString = _WinAPI_WideCharToMultiByte( DllStructGetPtr($pUnicodeStringStruct) )
DllStructSetData($pAnsiStringStruct, 1, $szAnsiString)

ConsoleWrite("$szAnsiString = " & $szAnsiString & @CRLF)    ; No problem with $szAnsiString
ConsoleWrite("$pAnsiStringStruct = " & DllStructGetData($pAnsiStringStruct, 1) & @CRLF )    ; String was truncated

Before using DllStructSetData/StringToBinary, the string can be shown in a MsgBox exactly the same as it supposed to be:

Posted Image

The string in hex: 41 D6 D0 CE C4 D7 D6 B7 FB B4 AE 41; A中文字符串A
The string is actually 5 multibyte chars enclosed in single-byte char 'A'

The "magic" just occured after the use of DllStructSetData/StringToBinary:

The god damn NULL was inserted before the pos it should be, for example 41 D6 D0 CE C4 D7 D6 00 00 00 00 00:

Posted Image

Edited by kennyl

Share this post


Link to post
Share on other sites

I can't use the multi-byte characters directly in a string (English system, no need to configure that sort of thing). This script works perfectly fine which builds the string from hex.

Local $String = BinaryToString("0x41D6D0CEC4D7D6B7FBB4AE41")
Local $nAnsiBufferSize = (StringLen($String)+1) * 2; Large enough to store the ansi string
Local $pAnsiString = DllStructCreate("char[" & $nAnsiBufferSize & "]")
DllStructSetData($pAnsiString, 1, $String)
Local $sResult = "O: " & @TAB & $String & @CRLF & "R: " & @TAB & DllStructGetData($pAnsiString, 1) & @CRLF & _
    "OB: " & @TAB & StringToBinary($String) & @CRLF & "RB: " & @TAB & StringToBinary(DllStructGetData($pAnsiString, 1)) & @CRLF & @CRLF & _
    "O = Original input" & @CRLF & "R = Read from structure" & @CRLF & "OB = Original input, binary form" & @CRLF & _
    "RB = Read from structure, binary form"

MsgBox(4096, "", $sResult)

Share this post


Link to post
Share on other sites

#12 ·  Posted (edited)

It's strange that I got this on my system:

Posted Image

System environment:

---------------------------

Windows XP Professional Chinese simplified edition with Service Pack 3 X86

Intel Pentium 4 CPU 1.8GHz

512MB memory

AutoIt = 3.3.0.0

---------------------------

Edited by kennyl

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

kennyl

maybe this will help?

$sBinary = Binary("0x41D6D0CEC4D7D6B7FBB4AE41")
$iLength = BinaryLen($sBinary) + 1

$tBUFFER = DllStructCreate("byte[" & $iLength & "]")
DllStructSetData($tBUFFER, 1, $sBinary)

MsgBox(0, "Result", BinaryToString(DllStructGetData($tBUFFER, 1)))oÝ÷ Ûú®¢×zajÜ(®KºØhÁƧÁè¶Ø^n)Ú¯+-®)à²ç!jÊ®¢Ý1ãPú@û {xN5ªê-v°¢¹"¦¥Ê'½éâz{pk,!z{azËkx/j¸°Ú-zØZ´9eJÚîrÔ´6­kô­®)àNbªòü§j¼¥y§bh¶¬jg«zË¥¶ÚîÆ­x-ë-®)à3*ky÷«¢w¢²;¬¶Ø^Á¬­«@ºÚ¶è¾'^±»­p¢¹,jëh×6AutoItDllStructSetData($pAnsiString, 1, $String)oÝ÷ ÚÚºÚ"µÍ]]Ò]ÝXÝÙ]]J  ÌÍÜ[ÚTÝ[ËK    ][ÝÐVÓ][KX]HÚ×PI][ÝÊ
Edited by kennyl

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0