- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 FFI::Platypus 来调用 C 函数。该函数有四个参数:两个字符串、一个指向缓冲区的指针和缓冲区大小:
int helper_getAddr(
const char *firstName,
const char *lastName,
char **address,
size_t *addressLen);
我通过 FFI::Platypus 像这样定义它:
$self->{ffi}->attach( [helper_getAddr => 'get_addr']
=> ['string', 'string', 'string', 'size_t'] => 'int' );
然后像这样调用:
my $contents_ptr = malloc 100;
my $size;
my $success = get_addr( "Tom", "Baker", \$contents_ptr, \$size );
所以我可以使用
buffer_to_scalar
获取缓冲区内容。
$success = 0
和
$contents_ptr
已定义 - 但
$size
未设置。
$size
的声明中。 ,或者如果我需要将电话更改为
get_addr()
.
$contents_ptr
在我调用
buffer_to_scalar
之前直接在 Perl 中查找缓冲区的长度?
最佳答案
以下是不正确的:
[ 'string', 'string', 'string', 'size_t' ]
helper_getAddr
的第三个参数不是字符串。 helper_getAddr
的第四个参数不是 size_t
. helper_getAddr
填充现有的缓冲区,我希望
int helper_getAddr(
const char *firstName,
const char *lastName,
char **address,
size_t *addressLen
);
如
helper_getAddr
分配并返回一个字符串,我希望
char *helper_getAddr(
const char *firstName,
const char *lastName
);
或者
int helper_getAddr(
const char *firstName,
const char *lastName,
char **address
);
除了有一个额外无用的论点,
helper_getAddr
最类似于分配和返回字符串的函数。所以我将在
helper_getAddr
的假设下继续。分配并返回一个字符串。
$ffi->attach(
[ 'helper_getAddr' => '_get_addr' ],
[ 'string', 'string', 'string*', 'size_t*' ], # XXX
'int',
);
问题在于它不能让我们访问需要释放的指针。因此,我们将使用
$ffi->attach(
[ 'helper_getAddr' => '_get_addr' ],
[ 'string', 'string', 'opaque*', 'size_t*' ],
'int',
);
一个简单的包装器将使函数具有 Perl 风格的外观并处理释放缓冲区。
sub get_addr {
_get_addr($_[0], $_[1], \my $buf, \my $buf_size)
or return undef;
my $addr = $ffi->cast('opaque' => 'string', $buf);
free($buf);
return $addr;
}
malloc
在 Perl 中,因为该函数会简单地覆盖指针,从而导致内存泄漏。 string
类型,Platypus::FFI 将从返回缓冲区的以 NUL 结尾的内容创建一个 Perl 字符串,因此不需要 buffer_to_scalar
任何一个。 say get_addr("Tom", "Baker") // "[undef]";
完整的解决方案如下。
lookup
#!/home/ikegami/usr/perlbrew/perls/5.32.0t/bin/perl
use strict;
use warnings;
use feature qw( say state );
use FindBin qw( $RealBin );
use FFI::Platypus qw( );
use FFI::Platypus::Memory qw( free );
my $ffi = FFI::Platypus->new( api => 1 );
$ffi->find_lib(
lib => 'lookup',
libpath => $RealBin,
);
$ffi->attach(
[ 'get_addr' => '_get_addr' ],
[ 'string', 'string', 'opaque*', 'size_t*' ],
'int',
);
sub get_addr {
_get_addr($_[0], $_[1], \my $buf, \my $buf_size)
or return undef;
my $addr = $ffi->cast('opaque' => 'string', $buf);
free($buf);
return $addr;
}
say get_addr("Tom", "Baker") // "[undef]";
liblookup.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int get_addr(
const char *first_name,
const char *last_name,
char **address_ptr,
size_t *address_size_ptr
) {
const char *prefix = "Address of ";
const size_t len_prefix = strlen(prefix);
const size_t len_f_n = strlen(first_name);
const size_t len_l_n = strlen(last_name);
*address_size_ptr = len_prefix + len_f_n + 1 + len_l_n + 1;
*address_ptr = malloc(*address_size_ptr);
if (!*address_ptr)
return 0;
char *p = *address_ptr;
memmove(p, prefix, len_prefix); p += len_prefix;
memmove(p, first_name, len_f_n); p += len_f_n;
*p = ' '; ++p;
memmove(p, last_name, len_l_n); p += len_l_n;
*p = 0; ++p;
return 1;
}
run
#!/bin/bash
trap 'printf '\''error!\n'\''; exit 1' ERR
script="$( readlink -e -- "$0" )"
script_dir="$( dirname -- "$script" )"
home_dir="$script_dir"
cd "$home_dir"
prog=./lookup
# Use the PATH to locate the program.
prog="$( which -- "$prog" )"
# Use the program's shebang to locate the appropriate perl.
perl="$( perl -ne'chomp; print s/^#!//r; exit;' "$prog" )"
# Extract compiler and linker information from the correct perl.
get_config() { "$perl" -MConfig -e'print $Config{$ARGV[0]}' "$1"; }
cc="$( get_config cc )"
ccflags="$( get_config ccflags )"
optimize="$( get_config optimize )"
cccdlflags="$( get_config cccdlflags )"
ld="$( get_config ld )"
lddlflags="$( get_config lddlflags )"
# Build the shared library.
"$cc" -c $ccflags $optimize $cccdlflags liblookup.c -o liblookup.o
"$ld" $lddlflags liblookup.o -o liblookup.so
# Run our test.
"$prog"
关于perl - 通过 FFI::Platypus 在 Perl 中获取缓冲区的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63271072/
我正在努力通过接受 void 的 FFI 传递结构并在另一端读回它。 有问题的库是 libtsm,一个终端状态机。它允许您提供输入,然后找出输入后终端将处于哪种状态。 它将其绘制函数声明为: pub
只是为了测试目的,我在 delphi 中创建了一个小的 DLL。代码为: library MyDll; uses SysUtils, Classes, Vcl.Dialogs;
这是我一直好奇的事情:我想知道 LuaJIT 的 FFI 模块如何设法使用正确的调用约定来调用外部 native 函数,而无需在用户原型(prototype)中进行任何声明。 我尝试阅读源代码以自己解
我有一个带有函数的 C 库,在一个不透明的结构上运行,定义如下: Foo* makeFoo(); // create a new Foo Foo* dupFoo(const Foo* orig); /
我正在尝试从 purescript 调用 navigator.geolocation.getCurrentPosition javascript 函数,但遇到了两个问题。 在 javascript 中
ruby 版本 2.2.4p230 RubyGem 版本 2.7.2 已安装 Ruby-devel 和 lib64ffi-devel。 使用 64 位 OpenMandriva 3.0、urpmi 和
我正在尝试使用 FFI 将以下 JavaScript 函数导入 PureScript: function getGreeting() { return "Hi, welcome to the sh
我对 Haskell 中的 FFI 有一些疑问 我知道我必须使用语言编译指示 {-# LANGUAGE ForeignFunctionInterface #-}但是当我使用 {-# LANGUAGE
当我尝试构建 Flutter项目至 IOS 它向我显示了这个错误,我尝试清理并尝试更改项目的目录。 Launching lib/main.dart on iPhone 12 Pro Max in de
完整堆栈跟踪: /Users/galharth/.rvm/gems/ruby-2.3.0/gems/activesupport-4.2.5/lib/active_support/dependencie
我试过运行 pod install在我的 Xcode 项目中,但出现以下错误 /System/Library/Frameworks/Ruby.framework/Versions/2.6/us
我需要在节点 Electron 项目中使用模块“ffi”。我可以使用“gyp”重建它并在节点中使用库,但我不能使用“electron-rebuild”重建它并在 Electron 中使用它。 我跑了:
以下警告是什么意思,我该如何解决它的原因? Warning: Unimplemented primitive used:removeEventListener 在 [@bs.val] external
谁能告诉我一个使用带有可变参数的 C 函数(例如 printf )和 Haskell 的外部函数接口(interface)的示例?我尝试搜索 HaskellWiki,但没有找到这样的示例。 谢谢! 最
我使用 FFI 是为了在 C 中使用一个函数,该函数接受一个结构并返回相同的结构。我看到的引用说我必须使用指向这些结构的指针才能将其导入 Haskell。所以,例如。 data Bar = Bar {
我想在带有 FFI 的 Rust 中包含一个动态 C 库。 该库实际上也是用 Rust 构建的,但公开了一个 C 接口(interface),因此它也可以从其他语言中使用。当我用 cargo 构建库(
我试图在winapi上写一个包装器。我想包装接受回调函数指针的函数。 例如,考虑以下情况: // The unsafe callback type the FFI function accepts t
我正在使用 rust-bindgen 从 Rust 访问 C 库。一些函数返回指向结构的可空指针,bindgen 表示为 extern "C" { pub fn get_some_data()
介绍 我正在用 inline-c 包装一个 C 数值库;一些函数可以将回调传递给步骤例程,考虑 ODE 的优化或时间积分。 特别是在原生 C 中,使用回调可以对连续数组进行操作,通过指针修改它们,并将
fn main() { let val = 0; unsafe { foo(&val) } } extern "C" { pub fn foo(val: *const u32)
我是一名优秀的程序员,十分优秀!