input = [0,1,2,3]
pointerof(input[0])
Resulting
cant take address of input[0]
input = [0,1,2,3]
pointer = (input.to_unsafe + 0)
p pointer.value
You can't take pointerof a call. Assign it to a local variable first:
input = [0,1,2,3]
value = input[0]
pointerof(value) # Pointer(Int32)@0x7ffea1e5fb7c
@z64
My usecase
ann = Genann.genann_init(2, 1, 2, 1)
input = [[0, 0], [0, 1], [1, 0], [1, 1]];
output = [0, 1, 0, 0];
300.times { |i|
Genann.genann_train(ann, input[0], output[0], 3);
Genann.genann_train(ann, input[1], output[1], 3);
Genann.genann_train(ann, input[2], output[2], 3);
Genann.genann_train(ann, input[3], output[3], 3);
}
@kostya Your example does works. Where can i learn more about pointer in crystal?
I currently learning binding a c library, and the library is passing a lot of pointer through parameter, which is confusing me a lot.
Let me know if there is a source code example or an article addressing this.
can you show fun declaration of genann_train?
It is based of https://github.com/codeplea/genann/blob/master/genann.h
I don't know if i'm correct
@[Link(ldflags: "#{__DIR__}/genann/genann.o")]
lib Genann
struct GenannActfun
ann: Genann*
a: Float64
end
struct Genann
inputs : Int32
hidden_layers : Int32
hidden : Int32
outputs : Int32
activation_hidden : GenannActfun
activation_output : GenannActfun
total_weights : Int32
total_neurons : Int32
weight : Pointer(Float64)
output : Pointer(Float64)
delta : Pointer(Float64)
end
fun genann_init(inputs : UInt32, hidden_layers : UInt32, hidden : UInt32, outputs : UInt32): Genann*
fun genann_train(ann : Genann*, inputs : Void*, desired_outputs : Float64*, learning_rate : Float64)
fun genann_run(ann : Genann*, inputs: Float64): Float64*
end
Tried https://github.com/crystal-lang/crystal_lib, but errored out on parsing typedef double (*genann_actfun)(const struct genann *ann, double a);
why inputs : Void*, it should be Float64*
this should work:
Genann.genann_train(ann, input[0].to_unsafe, output[0].to_unsafe, 3);
Whether the function wants input.to_unsafe + 0 or value = input[0]; pointerof(value) depends on how the C library is programmed. If you don't know how to work it out, you shouldn't be writing C bindings. You should understand C, pointers and the stack at the minimum before writing C bindings. It's easy to generate segfaults.
The error here is correct.
Also for a nice binding you actually want to hide all the pointers within your binding, the user should get Crystal datastructures & primitives or wrappers from your binding.