xsharp.eu • What happens with W2String() ? - Page 2
Page 2 of 2

What happens with W2String() ?

Posted: Fri Sep 28, 2018 10:04 am
by Karl-Heinz
Hi Chris,
Chris wrote: Instead of a PSZ, W2String() actually expects a pointer to a memory location containing a unicode string.
Exactly. To avoid misleadings, the correct W2String() VO-SDK declaration should be "AS PTR", instead of "AS PSZ".
Chris wrote: So, if I am not mistaken, this simpler function should also work fine:

Code: Select all

FUNCTION W2String(p AS PTR) AS STRING
	LOCAL IMPLIED cRet := System.Text.StringBuilder{}
	LOCAL nIndex AS INT
	LOCAL pChar AS WORD PTR
	nIndex := 1
	pChar := (WORD PTR)p
	DO WHILE pChar[nIndex] != 0
		cRet:Append(Convert.ToChar(pChar[nIndex]))
		pChar ++
	END DO
RETURN cRet:ToString()
i´ve tried it, and it works fine ! But what is the var "nIndex" good for, it´s always 1 ?

i think you mean:

DO WHILE pChar[nIndex] != 0
cRet:Append(Convert.ToChar(pChar[nIndex]))
nIndex ++
// pChar ++
END DO


or this one:


DO WHILE pChar[1] != 0
cRet:Append(Convert.ToChar(pChar[1]))
pChar ++
END DO


BTW. The size of the new download icon is impressiv :-)

regards
Karl-Heinz

What happens with W2String() ?

Posted: Fri Sep 28, 2018 11:59 am
by Chris
Karl-Heinz wrote: i´ve tried it, and it works fine ! But what is the var "nIndex" good for, it´s always 1 ?

i think you mean:

DO WHILE pChar[nIndex] != 0
cRet:Append(Convert.ToChar(pChar[nIndex]))
nIndex ++
// pChar ++
END DO
Oops, sorry, I indeed meant to write "nIndex ++" instead of "pChar ++". Funny that both work corectly though :)

Chris

What happens with W2String() ?

Posted: Wed Nov 28, 2018 6:54 am
by Karl-Heinz
Hi Chris

In the FileCopy.viaef ( see some msgs above) i deactivated the buildin W2String(), so the W2String() from the 2.0.0.7 runtime is used. But now W2String() causes at runtime an OutOfMemoryException, and when i debug an AccessViolationException is shown.

cMappedNewFile := W2String ( struMapping.pszNewPath )

It seems that this is the latest implementation.

/// <exclude />
FUNCTION W2String(p AS IntPtr) AS STRING
// The original code was using WideCharToMultiByte to determine the length of the string inside the ptr
// The Marshal implementation calls SysStringLen to determine the length
// and then creates a managed string with PtrToStringUni() passing in the ptr and the length
RETURN System.Runtime.InteropServices.Marshal.PtrToStringBSTR(p)


Lateron i´ll also take a look at the String2W() behaviour.

/// <exclude />
FUNCTION String2W( sz AS STRING ) AS IntPtr
// The original VO Code was using SysAllocString to allocate the memory.
// The Marshal class does that too (it uses SysAllocStringLen)
// and it also takes into account null strings
RETURN System.Runtime.InteropServices.Marshal.StringToBSTR(sz)


regards
Karl-Heinz

What happens with W2String() ?

Posted: Wed Nov 28, 2018 8:36 am
by Karl-Heinz
Karl-Heinz wrote:Hi Chris

Lateron i´ll also take a look at the String2W() behaviour.

/// <exclude />
FUNCTION String2W( sz AS STRING ) AS IntPtr
// The original VO Code was using SysAllocString to allocate the memory.
// The Marshal class does that too (it uses SysAllocStringLen)
// and it also takes into account null strings
RETURN System.Runtime.InteropServices.Marshal.StringToBSTR(sz)
String2W() works as expected. I only have to check how to free such allocated memory, till now SysFreeString() is used to do that.

regards
Karl-Heinz

What happens with W2String() ?

Posted: Wed Nov 28, 2018 8:43 am
by robert
Karl-Heinz,

Marshal.FreeBStr():
https://docs.microsoft.com/en-us/dotnet ... l.freebstr

Robert

What happens with W2String() ?

Posted: Wed Nov 28, 2018 12:31 pm
by Karl-Heinz
robert wrote:,

Marshal.FreeBStr():
Thanks Robert.

What happens with W2String() ?

Posted: Thu Nov 29, 2018 12:29 pm
by Chris
Looks like the new implementation of W2String() does not recognize the correct size of the string, in your sample I think it tries to convert all of the machine's memory into a string :). I think we need to revert to the previous implementation of the function.

What happens with W2String() ?

Posted: Thu Nov 29, 2018 3:36 pm
by Karl-Heinz
Hi Chris,

yes, the problem seems to be that Marshal.PtrToStringBSTR() does not always recognize the correct size of the string. That would explain the out of memory error. In my case "pszNewPath" is part of a structure, maybe that´s the problem. When i look with mem2string() at the "pszNewPath" content - i know the size ;-) - i don´t see what might be wrong with the content.

But W2String() works when i memcopy() the "pszNewPath" content and call W2String() with this pointer.

Code: Select all

      
       ....

	// cMappedNewFile := W2String ( struMapping.pszNewPath )  <--- crash

	LOCAL p AS PTR  
				
	? mem2string ( struMapping.pszNewPath , struMapping.cchNewPath * 2 ) +"*" 
	// D :  T e s t  t e s t c o p y f i l e  n e w   -   K o p i e   ( 2 0 ) . p d f *
	
		
	p := memalloc ( struMapping.cchNewPath * 2 )
 
	memcopy ( p , struMapping.pszNewPath , struMapping.cchNewPath * 2 )

	cMappedNewFile := w2string ( p )  // <-------- now it works ! 

        memfree ( p )


	// Fill REF var cNewFileName  
	cNewFileName := cMappedNewFile

        ....
regards
Karl-Heinz

What happens with W2String() ?

Posted: Fri Dec 21, 2018 11:02 am
by Karl-Heinz
Chris wrote:Looks like the new implementation of W2String() does not recognize the correct size of the string, in your sample I think it tries to convert all of the machine's memory into a string :). I think we need to revert to the previous implementation of the function.
it still fails with 2.0.0.8, so we must definitely revert to the previous implementation of the function ;-)

regards
Karl-Heinz

What happens with W2String() ?

Posted: Fri Dec 21, 2018 11:47 am
by Chris
Ah, sorry Karl-Heinz, forgot about this one. Will send you an updated today.