September 23, 2020, 01:36:19 pm

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Converting C to IWB

Started by Andy, August 10, 2017, 12:58:19 am

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Andy

Thanks for that, but it brings me back to the same old problem - how do you add a literal to X when you don't know before hand the value of X?

Many thanks again for trying!

Andy.
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

fasecero

Well, last attempt for me lol. I put aside the double problem by using the runtime functions, as jalih suggested. For some reason, I haven't been able to use c-runtime f that uses 64-bit variables (failed with DECLARE EXTERN approach and with LoadLibrary + GetProcAddress thing ), so I made a small vs dll that encapsulates the functions it needs. C++ source code included, just in case. Create an import library, place the dll at the same directory as the code below.

Code Select


SETPRECISION 0

' integer 64
INT64 num64 = 9223372036854775807q
print num64

' integer 64 to hex string
string str_16 = HEX$(num64)
print str_16

' integer 64 to decimal string
string str_10 = STR$(num64)
print str_10

' hex string to integer 64
INT64 num16 = VAL(str_16)
print num16

' decimal string to integer 64
INT64 num10 = VAL(str_10)
print num10

PRINT
PRINT
PRINT

' THE SAME USING THE DLL

$USE "cast64.lib"
DECLARE CDECL IMPORT, VAL64(string str, int base), INT64
DECLARE CDECL IMPORT, STR64(INT64 value, string buffer)
DECLARE CDECL IMPORT, HEX64(INT64 value, string buffer)

' integer 64
INT64 _num64 = 9223372036854775807q
print _num64

' integer 64 to hex string
string _str_16
HEX64(_num64, _str_16)
print _str_16

' integer64 to decimal string
string _str10
STR64(_num64, _str10)
print _str10

' hex string to integer 64
INT64 _num16 = VAL64(_str_16, 16)
print _num16

' decimal string to integer 64
INT64 _num10 = VAL64(_str10, 10)
print _num10

waitcon
end


Andy

I've come to the same conclusion, the only way for now is to write a Routine in another language that we can use.

I'm currently looking into a vb.net solution as I can understand that better than C and C ++

Andy.
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

ckoehn

QuoteClint I found you routine works, but if I just say bignumber = 12345678901234567890 directly it doesn't.


Like Jahil said, you need to add a q or uq to the end of a literal value.  IWBASIC limitation.  There is no way that making these routines in another language will help, because you could never transfer a int64 literal number from IWBASIC to that routine wiithout adding a q or uq. Just liike you have to now to use jahil or my routine.

Andy

But I can send a uint64 to a dll which returns a hex string, I'm only one step away from doing that, work permitting.
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

fasecero

QuoteI'm currently looking into a vb.net solution as I can understand that better than C and C ++


Ok, you'll find a way.

QuoteClint I found you routine works, but if I just say bignumber = 12345678901234567890 directly it doesn't.


Yeah about this, I'm just curious on how you can get a number like 12345678901234567890 without the "q". For example if I use some random function

Code Select
UINT64 ticks = GetTickCount64()

ticks variable will have an unknown value but it will have the "q" already attached.

jalih

August 14, 2017, 09:27:51 am #31 Last Edit: August 14, 2017, 09:29:29 am by jalih
Quote from: Andy on August 14, 2017, 08:54:30 am
But I can send a uint64 to a dll which returns a hex string, I'm only one step away from doing that, work permitting.

You can already send uint64 to IWB HEX$() function, use my routine or some other routine.  It's not the problem, your real problem is getting user or program input as uint64. As I already said, if data is binary data then you can just read it into 8 byte buffer and pass that to HEX$() routine.

Writing a function to validate ascii input and convert it to int64 is probably not that hard to write. Simple state machine can be used to validate input string and build uint64 from ascii digits.

We could write IVAL() function for IWB to handle 64-bit integers?

Andy

Yes, I agree about how you get a unit64, at the moment I'm focusing on registry qwords -  so the number has already been inputted.

Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

ckoehn

What is trying to be said here, if you already have a number in uint64 format, the routines already given you will work.  You don't need an external dll.

Andy

August 15, 2017, 05:10:05 am #34 Last Edit: August 15, 2017, 05:15:47 am by Andy
Clint,

Unless I'm missing something I cannot get a hex value greater than 7fffffffffffffff with the routines and qwords go all the way up to 16 f's.

Don't get me wrong - I really do appreciate the work you guys are doing on this!
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

jalih

Quote from: Andy on August 15, 2017, 05:10:05 am
Unless I'm missing something I cannot get a hex value greater than 7fffffffffffffff with the routines and qwords go all the way up to 16 f's.

Like Clint said, just read qword into 8-byte buffer and it will just work. You can use Union to map bytes into uint64.

Code Select

union dat
uint64 value
uint dword[2]
endunion

def num as dat

num.dword[0] = 0xffffffff
num.dword[1] = 0xffffffff

print hex$(num.value)

Andy

August 16, 2017, 12:09:34 am #36 Last Edit: August 16, 2017, 12:46:25 am by Andy
That's fantastic guys! - think maybe my brain cells were on a "go slow" for a while.

With the code amended I can read a qword and return it's hex string value - this means I can finish off my RegExport function which exports all values of a key to a file.

Code Select

$include "C:\\Include Files\\Registry\\registrylib.inc"

openconsole
print
print
print RegGetQWValueHex("HKEY_CURRENT_USER\\Software\\Test\\One","qword")
print
print
do:until inkey$ <> ""
closeconsole
end


So for registry Qwords I now have two functions for reading them:

RegGetQWValue - returns the decimal (uint64) value
RegGetQWValueHex - returns the hex string value.

I will post the library and include file when I'm done.

Thanks again!!!
:)
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.

fasecero

Just a side note. My dll works for INT64, anyway it can be easily ported for UINT64. But, today I give it another try by using c-runtime & 64 bits from the interface, without using a dll, and it seems that I succeeded. This problem is already solved by the union, I share it simply for the pleasure that gave me to achieve my goal xD

Code Select

$INCLUDE "windowssdk.inc"

' string to UINT64
UINT64 value = StringToUINT64("FFFFFFFFFFFFFFFF") ' hex number
print value

' UINT64 to string
string text = UINT64ToString(value)
print text

PRINT

WAITCON

' -------------------------------------------------------------------------------------
' C-Library Data Conversion Functions
' https://msdn.microsoft.com/en-us/library/0heszx3w.aspx
' -------------------------------------------------------------------------------------

DECLARE CDECL _strtoui64Template(pointer nptr, pointer endptr, uint base), UINT64

SUB StringToUINT64(string text), UINT64
UINT64 value = 0

UINT hInst=LoadLibrary("msvcrt.dll")

IF hInst THEN
UINT proc = GetProcAddress(hInst, "_strtoui64")

IF proc THEN
value = !<_strtoui64Template>proc(text, 0, 16)
ENDIF

FreeLibrary(hInst)
ENDIF

RETURN value
ENDSUB

DECLARE CDECL _ui64toa_sTemplate(UINT64 value, pointer buffer, INT sizeInCharacters, INT radix), INT

SUB UINT64ToString(UINT64 value), string
string buffer = ""

UINT hInst=LoadLibrary("msvcrt.dll")

IF hInst THEN
UINT proc = GetProcAddress(hInst, "_ui64toa_s")

IF proc THEN
value = !<_ui64toa_sTemplate>proc(value, buffer, 200, 16)
ENDIF

FreeLibrary(hInst)
ENDIF

RETURN UCASE$(buffer)
ENDSUB


Andy

August 17, 2017, 10:47:47 pm #38 Last Edit: August 17, 2017, 11:47:59 pm by Andy
Fasecero,

That is fantastic - great job!

A good while ago I wrote an alternative registry editor, but ran into difficulties when it came to adding / amending qwords.

I can now (when I have time) go back to the program and update it - your code will allow a user to add / amend a qword value (in hex) which can then be translated into a uint64 and saved.

Modifying this code in the StringToUINT64 sub with the line :
value = !<_strtoui64Template>proc(text, 0, 10)

also allows me to take a string decimal e.g. "12345678901234567890" and turn it into a uint64 of 12345678901234567890 which will enable a user to add / amend a qword with decimal as well. 

Thanks,
Andy.
Day after day, day after day, we struck nor breath nor motion, as idle as a painted ship upon a painted ocean.