@Araq, how do you know it's a callback?

When you create a proc to be used in C (callback):

  * Don't use exceptions
  * Don't use string or sequences
  * Deactivate stacktraces
  * Use `int32` or `cint` for `int` use `uint` or `csize_t` for `size_t`
  * tag `{.cdecl, gcsafe.}` your proc to detect at compile-time the issue



Also one thing I've noticed is that Nim `endOfFile()` is quitting to early 
compared to `c_eof` from the `system/ansi_c` module (see my h264 encoder test 
case 
[https://github.com/mratsim/trace-of-radiance/blob/99f7d85d/trace_of_radiance/io/h264.nim#L278](https://github.com/mratsim/trace-of-radiance/blob/99f7d85d/trace_of_radiance/io/h264.nim#L278))

Example to pass a Nim callback to C code for MP4 muxing:

[https://github.com/mratsim/trace-of-radiance/blob/99f7d85d/trace_of_radiance/io/mp4.nim#L115-L126](https://github.com/mratsim/trace-of-radiance/blob/99f7d85d/trace_of_radiance/io/mp4.nim#L115-L126)
    
    
    
    proc MP4E_open(
           sequential_mod_flag: cint,
           enable_fragmentation: cint,
           token: pointer,
           write_callback: proc(
             offset: int64,
             buffer: pointer,
             size: csize_t,
             token: pointer
           ): cint{.cdecl, gcsafe.}
         ): ptr MP4E_mux_t {.importc, header: "minimp4.h".}
      ## The C code
    
    
    {.push stackTrace: off.}
    proc writeToFile(
           offset: int64,
           buffer: pointer,
           size: csize_t,
           token: pointer
         ): cint {.cdecl, gcsafe.} =
      ## The callback
      let file = cast[File](token)
      file.setFilePos(offset)
      let bytesWritten = file.writeBuffer(buffer, size)
      return cint(bytesWritten.csize_t != size)
    {.pop.}
    
    
    Run

Reply via email to