我正在为Editline编写绑定,并且其中一个函数history执行了这部分库的大部分工作,但有几个可能的签名:
:(Pointer[Internal], Pointer[Event], int32 --> int32)
:(Pointer[Internal], Pointer[Event], int32, int32 --> int32)
:(Pointer[Internal], Pointer[Event], int32, Str --> int32)
# etc.
Run Code Online (Sandbox Code Playgroud)
第三个参数是一个标志,用于确定history应该使用给定的参数调用哪个函数,但由于这些符号未导出,因此我无法使用它们.我怎样才能找到使用该功能的方法?我不能使用多子或用于cglobal将其转换为a Pointer,然后使用正确的签名.
编辑:我知道is symbol,但我想知道是否有更好的方法可以解决这个问题,因为有9个不同的签名要写
我编写了一个 Raku 脚本来调用erfC 标准库中的函数:
use NativeCall;
sub erf(num64) returns num64 is native { * };
say [0.5,1,2,3,4,-0.9].map: {erf($_.Num)};
Run Code Online (Sandbox Code Playgroud)
该脚本的输出
(0.5204998778130465 0.8427007929497149 0.9953222650189527 0.9999779095030014 0.9999999845827421 -0.7969082124228322)
Run Code Online (Sandbox Code Playgroud)
[0.5,1,2,3,4,-0.9]除 之外的所有值都与 C 的输出匹配4。
对于4C 输出,1.000000而 Raku 给出0.9999999845827421。
要测试 C 语言的输出4,请运行以下代码:
#include <stdio.h> // Including header file for printf function
#include <math.h> // Including header file for erf function
int main (){
double param, result;
param = 4.0;
result = erf(param);
printf("erf …Run Code Online (Sandbox Code Playgroud) 主要是为了创建合理的示例,我想知道哪些数据结构和rountes可用于Perl6的native界面,如
class a-class is repr('CStruct') { has int $.whatever; }
class another-class is repr('CPPStruct') { has int $.whateverelse; }
sub a_native_function( another-class $object ) is native {*};
Run Code Online (Sandbox Code Playgroud)
有没有办法列出它们?我想特别获取C++函数和数据结构的示例,这样我就不必创建和编译外部库来创建示例.
在尝试公开localtimePerl 6中的功能时,我似乎做错了什么:
use NativeCall;
my class TimeStruct is repr<CStruct> {
has int32 $!tm_sec;
has int32 $!tm_min;
has int32 $!tm_hour;
has int32 $!tm_mday;
has int32 $!tm_mon;
has int32 $!tm_year;
has int32 $!tm_wday;
has int32 $!tm_yday;
has int32 $!tm_isdst;
has Str $!tm_zone;
has long $!tm_gmtoff;
}
sub localtime(uint32 $epoch --> TimeStruct) is native {*}
dd localtime(time); # segfault
Run Code Online (Sandbox Code Playgroud)
跑下perl6-lldb-m,我得到:
Process 82758 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x5ae5dda1)
frame #0: 0x00007fffe852efb4 libsystem_c.dylib`_st_localsub …Run Code Online (Sandbox Code Playgroud) 有没有一种方便的方法来处理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) {
...
}
Run Code Online (Sandbox Code Playgroud)
目前我在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); …Run Code Online (Sandbox Code Playgroud) 我如何使这项工作?
更新:在搜索包括 Raku 规范测试在内的 Github 之后,我还没有找到任何传递 CArray[of-structs] 的示例。 这里有克里斯托夫在 2017 年发表的一篇文章,给出了一个“解决方法”。
Christoph 的解决方案可能有效,但如果没有更好的方法,在 NativeCall 中会更好。
在 Github 上有一个使用 a 的 Rakudo 测试,int TakeAStructArray(Struct **structs)如果您可以编写一个 C 函数来重新打包其 args 以转发到 a ,这可能会有所帮助TakeAnArrayOfStruct( struct Struct[])。
下面,JJMerelo 秒我怀疑由于 Rakudo 中的错误而失败。
我有一个C函数,它使用类似于 NativeCall 文档中使用的 timespec 结构:
结构体{
int show2( struct TS ts[2] ) { printf( "show2: (1) %ld %ld (2) %ld %ld\n", ts[0].ot, ts[0].one, ts[ 1].ot, ts[1].one); 返回0;从C调用时工作正常。
从 Raku (moar) 调用不起作用:
class …Run Code Online (Sandbox Code Playgroud) multi我正在尝试在 Raku 代码中使用将函数包装在 中的函数C。\n这里我正在调用lchoose共享库中的函数。\n这是我的有效Rmath代码:
use NativeCall;\n\nconstant RMATH = "./Rmath"; # shared library\nsub lchoose(num64, num64) returns num64 \n is native( RMATH ) { * };\n\n# The C function signature is \n# double lchoose(double, double);\n\nsub r_lchoose($n,$r) {\n return lchoose($n.Num, $r.Num)\n}\n\nsay r_lchoose(9,8) # 2.1972245773362196\nRun Code Online (Sandbox Code Playgroud)\n但这是行不通的。代码继续运行/挂起。既不死亡也不抛出任何输出:
\n\nuse NativeCall;\n\nconstant RMATH = "./Rmath"; # shared library\nmulti lchoose(num64, num64) returns num64 \n is native( RMATH ) { * };\n\nmulti lchoose($n,$r) …Run Code Online (Sandbox Code Playgroud) 我正在尝试封装一个C结构,其中一个成员是一个指向结构的指针数组,而我在弄清楚如何执行它时遇到了问题.
假设C代码如下所示:
struct foo
{
unsigned char a;
};
struct bar
{
struct foo *f[5];
};
Run Code Online (Sandbox Code Playgroud)
这种代码有效:
use NativeCall;
class foo is repr('CStruct') {
has uint8 $.a;
}
class bar is repr('CStruct') {
has foo $.f1;
has foo $.f2;
has foo $.f3;
has foo $.f4;
has foo $.f5;
}
Run Code Online (Sandbox Code Playgroud)
但它太可怕了.
A CArray在这里没用,因为它只是一个指向数组的指针,而不是一个指针数组; 我不能使用类似的东西has A @.a,因为a repr('CStruct')不处理那种属性.
任何提示?
我理解这个问题涉及到特定于实现的域,但在这一点上,Rakudo/MoarVM的具体答案对我也有帮助.
我正在研究一些NativeCall模块,并想知道如何调试内存泄漏.一些内存在C库中处理,我在那里有一个很好的处理.我知道域名是我的责任,MoarVM在那里没有什么可以做的.我可以在MoarVM域中做什么?检查悬空物体,循环参考物等的最佳方法是什么?
在一系列操作结束时是否有一种方法,我认为我的所有Perl对象都超出范围说"运行垃圾收集并告诉我任何事情"?
我可以运行一些Rakudo/NQP/MoarVM特定代码来帮助我吗?这不是为了在生产中发布,只是为了在我开发时进行测试/诊断.
MoarVM中的垃圾收集提供了一个诱人的概述,但没有足够的信息让我对它做任何事情.
我正在尝试在Perl 6中声明以下C结构:
struct myStruct
{
int A[2]; //<---NEED to declare this
int B;
int C;
};
Run Code Online (Sandbox Code Playgroud)
我的问题是我不知道如何int A[2];使用内置的NativeCall api 声明该部件.
所以我所拥有的是:
class myStruct is repr('CStruct') {
has CArray[int32] $.A;
has int32 $.B;
has int32 $.C;
};
Run Code Online (Sandbox Code Playgroud)
但是,我知道该has CArray[int32] $.A;部分是错误的,因为它没有在我的结构中声明只占用2个int32大小的部分.