我正在使用NativeCall接口.
该库将多次调用我的回调函数.
这很好.我可以使用正确的签名声明我的回调,将其作为&callback传入,并且库调用sub就好了.
它还能够将有效负载void*指针设置为我想要的任何东西,并且它将包含在我的回调函数调用中.
我可以隐藏一个Perl Str,例如,在有效载荷中成功往返吗?
sub set_userdata(Pointer) returns int32 is native { ... }
sub set_callback(&callback(Pointer $userdata --> int32)) returns int32 is native { ... }
sub callback(Pointer $userdata) returns int32 {
my Str $mystring = ???
...
}
my Str $my-userdata-string;
set_userdata(???);
set_callback(&callback);
Run Code Online (Sandbox Code Playgroud)
看起来它可能适用于一些绑定,"是rw",nativecast()和/或.deref.
我想使用Perl 6及其NativeCall库在Windows 10上开发GTK + 3应用程序.我已经安装了MSYS2和GTK + 3,可以使用它运行一个示例GTK + 3 C程序.但我无法在MSYS2上安装Perl 6.我试图在网上搜索相关的博客或帖子,但我找不到任何解决方案.如何在MSYS2上安装Perl 6(Rakudo)?
我正在GetFullPathName使用perl6脚本映射Windows API NativeCall,因此我写了以下内容:
#!perl6
use NativeCall;
constant \WIN32_MAX_PATH = 260;
#I may use directly $path.IO.absolute()
sub Win32-GetFullPathName(
Str $lpFileName is encoded('utf16'),
int32 $nBufferLength,
#Str $lpBuffer is encoded('utf16') is rw,
Blob $lpBuffer is rw,
Str $lpFilenameIndex is rw)
returns int32
is native('kernel32.dll')
is symbol('GetFullPathNameW')
{ * }
my $path = '.';
my $fp-size = Win32-GetFullPathName(
$path, # $path ~ "\0", # <!-- this hack make it working fine
WIN32_MAX_PATH,
#my Str $fpath = ' ' x WIN32_MAX_PATH;
my …Run Code Online (Sandbox Code Playgroud) 我正在玩NativeCall以熟悉Perl6的那一面.当然,我首先尝试加载libstatgrab(还有什么?).
所以我从最简单的部分开始 - 主机信息.由于还没有集群支持,它只是一个结果 - 不用担心复杂化.
代码:
#!/usr/bin/env perl6
use v6;
use NativeCall;
enum sg_error (
SG_ERROR_NONE => 0,
SG_ERROR_INVALID_ARGUMENT => 1,
...
);
class sg_error_details is repr('CStruct') {
has int32 $.error;
has int32 $.errno_value;
has Str $.error_arg;
};
sub sg_init(int32 $ignore_errors) returns int32 is native('statgrab') { * };
enum sg_host_state (
sg_unknown_configuration => 0,
sg_physical_host => 1,
sg_virtual_machine => 2,
sg_paravirtual_machine => 3,
sg_hardware_virtualized => 4
);
class sg_host_info is repr('CStruct') {
has Str $.os_name;
has Str $.os_release;
has …Run Code Online (Sandbox Code Playgroud) 我正在尝试将此代码移植到Perl6。虽然我可以打电话GetStdHandle,GetConsoleMode而且SetConsoleMode,我的脚本休息,当我试图调用ReadConsoleInput:
Cannot locate symbol 'ReadConsoleInput' in native library 'Kernel32.dll'
in method setup at C:\rakudo\share\perl6\sources\947BDAB9F96E0E5FCCB383124F923A6BF6F8D76B (NativeCall) line 287
in method CALL-ME at C:\rakudo\share\perl6\sources\947BDAB9F96E0E5FCCB383124F923A6BF6F8D76B (NativeCall) line 576
in block <unit> at test.p6 line 149
Run Code Online (Sandbox Code Playgroud)
现在,该函数肯定在那里。但是它有一个复杂的签名,我不确定我的脚本是否正确。那可能是原因吗?NativeCall是否查看签名?
这就是我在代码中定义子项的方式(注释摘自MS文档)
#BOOL WINAPI ReadConsoleInput( _In_ HANDLE hConsoleInput, _Out_ PINPUT_RECORD lpBuffer, _In_ DWORD nLength, _Out_ LPDWORD lpNumberOfEventsRead );
sub ReadConsoleInput(Pointer[void], INPUT_RECORD is rw, uint32, uint32 is rw) is native('Kernel32') returns Bool { * };
Run Code Online (Sandbox Code Playgroud)
如果需要,我可以发布其余的代码,但这是很多样板,因为我必须定义所有结构和内容,这些结构和内容通常来自头文件。
我正在尝试GetConsoleScreenBufferInfo(HANDLE, PCONSOLE_SCREEN_BUFFER_INFO)使用Perl 6和(当然)NativeCall从Windows API 使用该函数。
我想我已经CONSOLE_SCREEN_BUFFER_INFO正确设置了功能需要的结构,但是当我尝试转储其内容时,代码在调用后崩溃。
这是证明问题的最短的方法(不是很完全,但是很接近):
use NativeCall;
constant \HANDLE := Pointer[void];
constant \SHORT := int16;
constant \USHORT := uint16;
constant \WORD := uint16;
constant \DWORD := uint32;
constant \BOOL := int32;
constant \STD_OUTPUT_HANDLE := -11;
constant \STD_INPUT_HANDLE := -10;
class COORD is repr('CStruct') {
has SHORT $.X;
has SHORT $.Y;
}
class SMALL_RECT is repr("CStruct") {
has SHORT $.Left;
has SHORT $.Top;
has SHORT $.Right;
has SHORT $.Bottom;
};
class CONSOLE_SCREEN_BUFFER_INFO is repr("CStruct") { …Run Code Online (Sandbox Code Playgroud) 这是我的cpp代码:
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
double normalCDF( double x )
{
return 0.5 * ( 1.0 + erf( M_SQRT1_2 * x ) );
}
int main() {
cout << normalCDF(4.8) << endl;
cout << normalCDF(5.4) << endl;
cout << normalCDF(5.6) << endl;
cout << normalCDF(5.8) << endl;
cout << normalCDF(5.1) << endl;
cout << normalCDF(-37.5) << endl;
cout << normalCDF(-36.0) << endl;
cout << normalCDF(-37.6) << endl;
cout …Run Code Online (Sandbox Code Playgroud) 我想打电话给CHISQ功能的累积分布函数在GSL从乐。
这是我的乐曲脚本 chisq.raku
#Calling gsl_cdf_chisq-P function in GSL from raku
use NativeCall;
sub gsl_cdf_chisq_P(num64, num64) returns num64 is native('gsl') { * };
sub gsl_cdf_chisq_Q(num64, num64) returns num64 is native('gsl') { * };
sub pchisq($q, $df, $lower-tail = True) {
my $a = $q.Num;
my $b = $df.Num;
if $lower-tail == True {
return gsl_cdf_chisq_P($a, $b)
} else {
return gsl_cdf_chisq_Q($a, $b)
}
}
say pchisq(3,4);
Run Code Online (Sandbox Code Playgroud)
执行此脚本时,出现以下错误:
Cannot locate native library '(null)': /usr/lib/x86_64-linux-gnu/libgsl.so: undefined symbol: cblas_ctrmv …Run Code Online (Sandbox Code Playgroud) 根据Rust FFI Omnibus,以下内容应该有效。
\n这是一个名为“foo”的 Rust cdylib,lib.rs用 Cargo build 制作...
use std::convert::From;\n\n// Rust FFI Omnibus: Tuples \n// http://jakegoulding.com/rust-ffi-omnibus/tuples/\n\n// A Rust function that accepts a tuple\nfn flip_things_around_rust(tup: (u32, u32)) -> (u32, u32) {\n let (a, b) = tup;\n (b + 1, a - 1)\n}\n\n// A struct that can be passed between C and Rust\n#[repr(C)]\npub struct Tuple {\n x: u32,\n y: u32,\n}\n\n// Conversion functions\nimpl From<(u32, u32)> for Tuple {\n fn from(tup: (u32, u32)) -> Tuple {\n Tuple …Run Code Online (Sandbox Code Playgroud) 我想从 Raku 调用 C 函数https://github.com/wch/r-source/blob/trunk/src/nmath/rmultinom.c#L47。\n为此,我将 Raku 函数定义为
\nuse NativeCall;\nconstant RMATH = "./Rmath.dll";\nmulti set_seed(uint32, uint32)\n is native( RMATH ) { * };\nmulti set_seed(UInt() $a, UInt() $b) is export {\n set_seed(my uint32 $ = $a, my uint32 $ = $b)\n}\nsub rmultinom(int32, CArray[num64], int32, CArray[int32])\n is native( RMATH ) { * }; \n\nsub raku_rmultinom($n , $size, @prob is copy) is export {\n @prob = @prob.map: {$_.Num};\n my $prob = CArray[num64].new(@prob);\n my $ints = CArray[int32].allocate($size);\n rmultinom($n, $prob, $size, $ints);\n return $ints.list\n}\n …Run Code Online (Sandbox Code Playgroud)