2. How to dereference that pointer ? See this code sample
type Sample = object of RootObj
intVar : int
strVar : string
var abc = Sample
var p = cast[int](addr(abc))
So here i have an integer "p" and i need to convert it to a pointer again and i also need to get the data "abc" from that pointer. Any help would be appreciated. Thanks. Ok, i 've got the partial answer.
var s = cast[ref Sample](p)[]
Now, one question arises. Is it possible to keep the type name and use it when needed ? I mean ;
var abc = Sample
var p = cast[int](addr(abc))
By this time, i know p is an int form of a pointer which pointing to a Sample object. I can keep p in a seq. Similarly, how can i store the type name "Sample" in order to use later ?You can cast[ptr T](yourInt), and to dereference: yourPtr[].
Instead of int I strongly suggest you to use ByteAddress.
Here is an example of using pointer<->int conversion to align a pointer on 64-bit boundary. Source.
import typetraits
const LASER_MEM_ALIGN = 64
func align_raw_data*(T: typedesc, p: pointer): ptr UncheckedArray[T] =
static: assert T.supportsCopyMem
let address = cast[ByteAddress](p)
let aligned_ptr = block:
let remainder = address and (LASER_MEM_ALIGN - 1) # modulo LASER_MEM_ALIGN (power of 2)
if remainder == 0:
cast[ptr UncheckedArray[T]](address)
else:
let offset = LASER_MEM_ALIGN - remainder
cast[ptr UncheckedArray[T]](address +% offset) # +% interpret the operands as unsigned
return aligned_ptr
Thank you mratsim. I will use ByteAddress instead of int. Anyway, Can you please guide me on this ?
type
ListClass = ref object
typ : typedesc
pointR : ByteAddress
var x = new ListClass
x.typ = string
x.pointR = cast[ByteAddress](addr("A sample string"))
var y : seq[ListClass]
y.add(x)
# Then later...
var z = cast[ref y[0].typ](y[0].pointR)
echo z[] # Here i want to print "A sample string"
Don't cast to refs, strings or sequences, those types are tracked by the garbage collector and the cast will not register those pointers with the garbage collector.
Also I'm surprised you can have a typedesc field as in:
type
ListClass = ref object
typ : typedesc
pointR : ByteAddress
I want to include type name in that user defined type. Is it possible ?
You can of coarse do anything with "type names" - i.e. just strings "int", etc. But you probably want to store types themselves - typedesc. There's not so much you can do with them. Types exist at compile-time only (opposite to Ruby, Python and the like). Pointers - at run-time only. So no addr Sample and the like. It's possible to store types in compile-time variables (like var a {.compiletime.}: array[10,typedesc]), but even then you cannot then use them in place of types (like var x: a[0]).
Types exist at compile-time only (opposite to Ruby, Python and the like).
I just want to check the type at runtime and want to make some changes in program. So i am assuming i cant do it in nim.
It is just an experiment. I love ArrayList in vb.net and list in python. I am trying to implement something like them in Nim. I know, that most of the time we can make a user defined type and declare a seq contains that type will work. But this is also a good feature of a language.
This is my aim -
3. Keep it in a seq Then later loop through the seq, find the ByteAddress with an index. Then convert it back to the actual pointer. But afaik, I need to use the type name to get the pointer.
@kcvinu This is a very interesting experiment, and I'll be interested in seeing if it's possible for it to work well.
Still, keep in mind, that this is just veeery unusal in normal Nim code: I doubt I'll ever use anything like that even if it works, because 1) one can use normal types / variants in 95% of the cases 2) it's probably slower 3 ) it seems very type unsafe. It might make sense for Python/Ruby, but it's not needed for Nim code.
But, if you look at it as just an experiment, it's pretty interesting.
But then the if statement makes not much sense any more, it should be a when. But when is compile time of course. So for me here is no actual runtime test at all.
I thought if is used in run-time while when is for compile-time, is not like that?
I thought if is used in run-time while when is for compile-time, is not like that?
Generally it is of course.
But I just tested what I wrote above, and my memory was indeed correct: "echo (a +1)" does not compile for your example code, but replacing if with when makes it compile again. As the proc is generic, type of parameter a is know at compile time for each instance of proc, so the test "if a is int" compiles but makes not much sense.