Groups keyboard shortcuts have been updated
Dismiss
See shortcuts

Utilizing inttypes.h format specifiers

232 views
Skip to first unread message

jric...@gmail.com

unread,
Sep 17, 2020, 12:41:58 AM9/17/20
to cython-users
Hi everyone,

I'm working on something that needs to be cross platform, and I have uint64_t and int64_t variables I need to use in printf and snprintf calls.  I landed on using the "PRIu64" and "PRId64" format specifiers from inttypes.h (if you have a better suggestion for cross platform support, please let me know!), which is working well on both windows and linux for my code that is pure c, but I'm not sure how to implement it in the cython portions of my code.  This is also complicated by the fact that I'll be using it in a nogil block.

The standard C usage of PRIu64 would be

#include <inttypes.h>

uint64_t number = 5000;
printf("number = %" PRIu64 "\n", number);


I have the below code in a separate .pyd that I cimport from (though I'm not sure if this is the proper way to utilize a C string literal of variable length that was defined):

cdef extern from "<inttypes.h>" nogil:
     char *PRIu64
     char *PRId64


When attempting to use in cython code, it only seems to work if I remove "nogil", and use the standard "+" based string concatenation:
printf("%" PRIu64 "other text" , number)
        error: Expected ')', found 'PRIu64'

printf("%" + PRIu64 + "other text" , number)
        error: Operation not allowed without gil (on the "+")
        error: Converting to Python object not allowed without gil (on PRIu64)

The last one works without nogil.

Any thoughts on how to utilize these format specifiers in cython?  Thank you for the help!



da-woods

unread,
Sep 19, 2020, 3:39:21 AM9/19/20
to cython...@googlegroups.com
I don't think there's an easy way to tell Cython that these are C string literal and thus it should allow C-style concatenation when they're next to other C string literals. The best workaround that I can think of would be to define the concatenated strings in C (at the top of your file):

cdef extern from *:
    """
    const char NUMBER_EQUALS_STR[] = "number = %" PRIu64 "\n";
    """
    const char* NUMBER_EQUALS_STR

Then in Cython:

printf(NUMBER_EQUALS_STR , number)
--

---
You received this message because you are subscribed to the Google Groups "cython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cython-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/cython-users/f61c4946-1130-46e3-8f4c-56966d99838bn%40googlegroups.com.


jric...@gmail.com

unread,
Sep 21, 2020, 11:57:25 PM9/21/20
to cython-users
Oh that's perfect, thanks!  Hadn't thought to pre-concatenate, let alone combine with an "extern from *", but that's perfect for my use case.  Cheers!
Reply all
Reply to author
Forward
0 new messages