使用 NativeCall 在不同平台上处理 C typedef
Handle C typedef on different platform using NativeCall
有没有一种方便的方法来处理在不同平台上可能具有不同值的 C typedef?
例如
#if defined(_WIN32)
#define foo_t int32_t
#elif defined(_WIN64)
#define foo_t int64_t
#else
#define foo_t long
#endif
void handle_foo(foo_t* in) {
...
}
目前我在 Perl 6 中是这样处理的
sub handle_foo32(int32 is rw) is native(Str) { * }
sub handle_foo64(int64 is rw) is native(Str) { * }
sub handle_foo00(long is rw) is native(Str) { * }
sub handle-foo(Int $in) {
if $*DISTRO.is-win {
given $*KERNEL.bits {
when 32 {
handle_foo32(my int32 $ = $in);
}
when 64 {
handle_foo64(my int64 $ = $in);
}
}
} else {
handle_foo00(my long $ = $in);
}
}
我不这么认为。但由于 $*DISTRO.is-win
和 $*KERNEL.bits
是有效的常量,您可以将使用哪个版本的决定移至编译时:
sub handle_foo32(int32 is rw) is native(Str) { * }
sub handle_foo64(int64 is rw) is native(Str) { * }
sub handle_foo00(long is rw) is native(Str) { * }
my constant &handler = $*DISTRO.is-win
?? $*KERNEL.bits == 32
?? &handle_foo32
!! &handle_foo64
!! &handle_foo00;
除此之外,这当然不会帮助您处理每个版本的不同大小的参数。所以我猜你需要另一层间接访问。
也许是灵感,以下是我处理类似问题的方式:https://github.com/lizmat/P5getpwnam/blob/master/lib/P5getpwnam.pm6
也许最直接的翻译是使用constant
引入一个新的符号,在编译时计算。
my constant foo_t = do if $*DISTRO.is-win {
given $*KERNEL.bits {
when 32 { int32 }
when 64 { int64 }
}
} else {
long
}
绑定到类型对象的常量就像类型一样,可以在签名中使用。
sub handle_foo(foo_t is rw) is native { * }
有没有一种方便的方法来处理在不同平台上可能具有不同值的 C typedef?
例如
#if defined(_WIN32)
#define foo_t int32_t
#elif defined(_WIN64)
#define foo_t int64_t
#else
#define foo_t long
#endif
void handle_foo(foo_t* in) {
...
}
目前我在 Perl 6 中是这样处理的
sub handle_foo32(int32 is rw) is native(Str) { * }
sub handle_foo64(int64 is rw) is native(Str) { * }
sub handle_foo00(long is rw) is native(Str) { * }
sub handle-foo(Int $in) {
if $*DISTRO.is-win {
given $*KERNEL.bits {
when 32 {
handle_foo32(my int32 $ = $in);
}
when 64 {
handle_foo64(my int64 $ = $in);
}
}
} else {
handle_foo00(my long $ = $in);
}
}
我不这么认为。但由于 $*DISTRO.is-win
和 $*KERNEL.bits
是有效的常量,您可以将使用哪个版本的决定移至编译时:
sub handle_foo32(int32 is rw) is native(Str) { * }
sub handle_foo64(int64 is rw) is native(Str) { * }
sub handle_foo00(long is rw) is native(Str) { * }
my constant &handler = $*DISTRO.is-win
?? $*KERNEL.bits == 32
?? &handle_foo32
!! &handle_foo64
!! &handle_foo00;
除此之外,这当然不会帮助您处理每个版本的不同大小的参数。所以我猜你需要另一层间接访问。
也许是灵感,以下是我处理类似问题的方式:https://github.com/lizmat/P5getpwnam/blob/master/lib/P5getpwnam.pm6
也许最直接的翻译是使用constant
引入一个新的符号,在编译时计算。
my constant foo_t = do if $*DISTRO.is-win {
given $*KERNEL.bits {
when 32 { int32 }
when 64 { int64 }
}
} else {
long
}
绑定到类型对象的常量就像类型一样,可以在签名中使用。
sub handle_foo(foo_t is rw) is native { * }