fbpx
Welcome, Guest
Username: Password: Remember me
  • Page:
  • 1

TOPIC: What happens with W2String() ?

What happens with W2String() ? 5 months 3 weeks ago #1

  • Karl-Heinz
  • Karl-Heinz's Avatar Topic Author
  • Offline
  • Posts: 189
String2W() already exists, but for compatibility reasons i also need W2String(). Sure, i could add such a func to a lib of my own, but are there any plans to add string2W() to the #X runtime ?

regards
Karl-Heinz

Please Log in or Create an account to join the conversation.

What happens with W2String() ? 5 months 3 weeks ago #2

Hi karl-Heinz,

I think this function is not needed, because strings are anyway unicode in .Net. So if you are using it with STRINGs, then it is not needed at all, if you use it with PSZs you can just use Psz2String() instead, or define it as

FUNCTION W2String(pStr AS PSZ) AS STRING
RETURN Psz2String( pStr )

Btw, in the vulcan runtime there were implicit conversions from/to STRING<->PSZ, so you could simply just use

cString := pPsz
or
pPsz := cString

and the runtime would take care of the conversions automatically. We haven't done that in x#, not sure we should though, seeing it again I think it was probably too much happening under the hood in the vulcan runtime there.

Chris
XSharp Development Team
chris(at)xsharp.eu

Please Log in or Create an account to join the conversation.

What happens with W2String() ? 5 months 3 weeks ago #3

  • Karl-Heinz
  • Karl-Heinz's Avatar Topic Author
  • Offline
  • Posts: 189
Hi Chris,

Chris wrote:
I think this function is not needed, because strings are anyway unicode in .Net. So if you are using it with STRINGs, then it is not needed at all, if you use it with PSZs you can just use Psz2String() instead, or define it as

FUNCTION W2String(pStr AS PSZ) AS STRING
RETURN Psz2String( pStr )


i think that can´t work because the X# psz2string() truncates - correctly - a widestring as VO does. What i´m currently using is the VO W2String() code. i´ll have to do some tests with structures that hold widestrings, and if there are no problems and no other solution i´ll stay with the VO code.

_DLL FUNC WideCharToMultiByte(CodePage AS DWORD, dwFlags AS DWORD, lpWideCharStr AS PTR ,;   //  INTPTR
	cchWideChar AS INT, lpMultiByteStr AS PSZ,;
	cchMultiByte AS INT,lpDefaultChar AS PSZ,;
	lpUsedDefaultChar AS LOGIC PTR );   // INTPTR
	AS INT PASCAL:KERNEL32.WideCharToMultiByte	 
		
FUNCTION W2String2       (bstrVal AS PSZ)    AS STRING  
	
	RETURN psz2string ( bstrVal )	
   
FUNCTION W2String       (bstrVal AS PSZ)    AS STRING  // VO-SDK code

	LOCAL pBuff    := NULL  AS PTR  // INTPTR
	LOCAL cRet          AS STRING
	LOCAL nSize         AS INT

	//  Get Size
	nSize := WideCharToMultiByte(CP_ACP, 0,  bstrVal, -1, pBuff, 0, NULL_PSZ, NULL_PTR) 
	
	IF nSize > 0
		pBuff := MemAlloc( DWORD(nSize) + 1)   
		IF pBuff != NULL_PTR
			//  Convert to VO string
			WideCharToMultiByte(CP_ACP, 0,  bstrVal, -1, pBuff, nSize, NULL_PSZ, NULL_PTR)
			cRet := Mem2String(pBuff, DWORD(nSize) -1 )   //  -1 added KHR
		ENDIF
		MemFree(pBuff)
	ENDIF 
	
	
	RETURN cRet	
	

DEFINE CP_ACP := 0 	
	

FUNCTION Start(  ) AS VOID

// The x# runtime already knows String2W().
// /unsafe must be checked to compile.

? "*" + w2string ( string2w ( "Teststring" ) ) + "*"    // "*TestString*"
? "*" + w2string2 ( string2w ( "Teststring" ) ) + "*"   // "*T*"


RETURN

regards
Karl-Heinz

Please Log in or Create an account to join the conversation.

What happens with W2String() ? 5 months 3 weeks ago #4

Karl-Heinz,

Can you explain why you need this.

Robert
XSharp Development Team
The Netherlands
This email address is being protected from spambots. You need JavaScript enabled to view it.

Please Log in or Create an account to join the conversation.

What happens with W2String() ? 5 months 3 weeks ago #5

  • Karl-Heinz
  • Karl-Heinz's Avatar Topic Author
  • Offline
  • Posts: 189
Hi Robert,

in the attached Filecopy.viaef there is a stripped VO func - CopyFromTo() - that detects if during a filecopy a new filename was created - something like "new.pdf" became e.g. "new - kopie (6).pdf". I have access to such a new filename in the CopyFromTo() line:

cMappedNewFile := W2String ( struMapping.pszNewPath )

Without W2String() i get a truncated filename. Only the first char is shown, instead of the full new filename.

To ensure that a correct source dir and filename is used, you are forced to take a look at the start() code, otherwise the only console output will be "done" ;-)

regards
Karl-Heinz
Attachments:

Please Log in or Create an account to join the conversation.

What happens with W2String() ? 5 months 3 weeks ago #6

  • Karl-Heinz
  • Karl-Heinz's Avatar Topic Author
  • Offline
  • Posts: 189
mmmmh, it seems that the attachment isn´t visible ? Next try with a zip file ...
let me know if the attachment is still not visible.
Attachments:

Please Log in or Create an account to join the conversation.

What happens with W2String() ? 5 months 3 weeks ago #7

Nothing attached...

Please Log in or Create an account to join the conversation.

Last edit: by FFF. Reason: typo

What happens with W2String() ? 5 months 3 weeks ago #8

  • Karl-Heinz
  • Karl-Heinz's Avatar Topic Author
  • Offline
  • Posts: 189
i see two empty rectangles, that´s all ?


www.rauscher-software.de/downloads/Filecopy.ZIP

Please Log in or Create an account to join the conversation.

What happens with W2String() ? 5 months 3 weeks ago #9

Hi Karl-Heinz,

Ah, thanks, so W2String() does not work with PSZs (at least in the VO sense of PSZ) as its parameter type in the misleading definition in VO implies. If you try this code in VO, then you will not get correct results either:
FUNCTION Start() AS INT
LOCAL p AS PSZ
p := String2Psz("ABC")
? W2String(p)

Instead of a PSZ, W2String() actually expects a pointer to a memory location containing a unicode string. So, if I am not mistaken, this simpler function should also work fine:
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()

Please give it a try, if it works as expected we can add it to the runtime.

About the attachments, yeah, I see it as well, it does not work well. But for all your attachments, I could download them by using right-click and use "Save link as" from teh context menu.

Chris
XSharp Development Team
chris(at)xsharp.eu

Please Log in or Create an account to join the conversation.

What happens with W2String() ? 5 months 3 weeks ago #10

Karl-Heinz,
There was a problem in the template for the forum.
It should be fixed now. You should see icons in stead of empty boxes.

Robert
XSharp Development Team
The Netherlands
This email address is being protected from spambots. You need JavaScript enabled to view it.

Please Log in or Create an account to join the conversation.

What happens with W2String() ? 5 months 3 weeks ago #11

  • Karl-Heinz
  • Karl-Heinz's Avatar Topic Author
  • Offline
  • Posts: 189
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:

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

Please Log in or Create an account to join the conversation.

What happens with W2String() ? 5 months 3 weeks ago #12

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
XSharp Development Team
chris(at)xsharp.eu

Please Log in or Create an account to join the conversation.

What happens with W2String() ? 3 months 3 weeks ago #13

  • Karl-Heinz
  • Karl-Heinz's Avatar Topic Author
  • Offline
  • Posts: 189
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

Please Log in or Create an account to join the conversation.

What happens with W2String() ? 3 months 3 weeks ago #14

  • Karl-Heinz
  • Karl-Heinz's Avatar Topic Author
  • Offline
  • Posts: 189

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

Please Log in or Create an account to join the conversation.

What happens with W2String() ? 3 months 3 weeks ago #15

XSharp Development Team
The Netherlands
This email address is being protected from spambots. You need JavaScript enabled to view it.

Please Log in or Create an account to join the conversation.

What happens with W2String() ? 3 months 3 weeks ago #16

  • Karl-Heinz
  • Karl-Heinz's Avatar Topic Author
  • Offline
  • Posts: 189

robert wrote: ,

Marshal.FreeBStr():


Thanks Robert.

Please Log in or Create an account to join the conversation.

What happens with W2String() ? 3 months 3 weeks ago #17

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.
XSharp Development Team
chris(at)xsharp.eu

Please Log in or Create an account to join the conversation.

What happens with W2String() ? 3 months 3 weeks ago #18

  • Karl-Heinz
  • Karl-Heinz's Avatar Topic Author
  • Offline
  • Posts: 189
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.

       ....

	// 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

Please Log in or Create an account to join the conversation.

What happens with W2String() ? 3 months 2 days ago #19

  • Karl-Heinz
  • Karl-Heinz's Avatar Topic Author
  • Offline
  • Posts: 189

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

Please Log in or Create an account to join the conversation.

What happens with W2String() ? 3 months 2 days ago #20

Ah, sorry Karl-Heinz, forgot about this one. Will send you an updated today.
XSharp Development Team
chris(at)xsharp.eu

Please Log in or Create an account to join the conversation.

  • Page:
  • 1