xsharp.eu • Pointer conversion
Page 1 of 1

Pointer conversion

Posted: Fri Nov 25, 2016 11:20 am
by ArneOrtlinghaus
Hello,
I need some help casting pointers in some ugly, old winapi functions:

Error XS1503 Argument 5: cannot convert from 'void*' to 'byte*'

local nValue as dword
...
nRet := RegSetValueEx( pSubKey, ;
String2Psz(cValueName), ;
0, ;
REG_DWORD, ;
ptr(_cast, @nValue),;
DWORD(nSize) )

Error XS1503 Argument 3: cannot convert from 'void*' to 'word*'

local pUnicode as ptr
...

iNum := dword(WideCharToMultiByte(;
ncp,; // CodePage AS DWORD
0,; // dwFlags AS DWORD
pUnicode,; // lpWideCharStr AS PSZ
isLen,; // cchWideChar AS INT
null_psz,; // lpMultiByteStr AS PSZ
0,; // cchMultiByte AS INT
null_ptr,; // lpDefaultChar AS PSZ
null_ptr )) // lpUsedDefaultChar AS LOGIC PTR

Pointer conversion

Posted: Fri Nov 25, 2016 1:00 pm
by robert
Arne,

Your example is exactly the kind of code that I am working on at this moment in the X# compiler. These "ugly" casts (ptr(_cast, @nValue)) and passing an untyped pointer to a API function that is declared to receive a typed pointer (pUnicode is declared as PTR but the API expects a WORD *) are considered unsafe in DotNet.

The fact that these things are normally not allowed in DotNet is also one of the reasons that DotNet apps are usually more stable than unmanaged C++ and VO apps.

You can solve this yourself by making the following changes:

- Declare pUnicode as WORD PTR
- Cast the @nValue to a BYTE PTR: (Byte PTR) @nValue

Of course it would be even better if you changed your code and would switch to the .Net Registry class. That class takes care of all conversions and dirty work for you.

And I am not sure where you need WideCharToMultiByte() ? In DotNet the strings are all Unicode, so there usually is no need to convert anything, unless you want to write stuff in Ansi. In that case I advise you take a look at the System.Runtime.InteropServices.Marshal Class. This class has methods like StringToHGlobalAnsi(), StringToBSTR() etc. and of course methods like FreeHGlobal() and FreeBstr() to free the allocated strings.


Robert


Robert

Pointer conversion

Posted: Fri Nov 25, 2016 1:31 pm
by ArneOrtlinghaus
Robert,
thank you for the answer.
I will try with the changes you described.

It is true, that it would be better to change to the dotnet classes, but I want to do it only in small parts. I tried already to replace the registry functions by the dot net classes and then I found so many exceptions where the classes returned other values than the old functions that I decided to stay with the old as long as possible.

I will still need WideCharToMultiByte for some conversions to other code pages like UTF8. It is true, that there are better ways, but... ... unfortunately there are many, many other WinAPI functions existing.

Arne