使用 Xptr 和 Function 调用 Rcpp 函数 - 仅 xptr 情况有效

2024-04-13

我正在尝试开发一个包,其中我需要输入用户的函数(可以使用定义Rcpp or in R),将其发送到另一个函数(在包内)struct并在那里处理它。

当我使用Rcpp::Xptr(即函数指针)代码可以工作,但同样不起作用Rcpp::Function。使用的优点Rcpp::Function对于用户来说,他们将能够在中定义函数R(尽管损失了很多性能增益)。

首先什么有效:

#include <Rcpp.h>
using namespace Rcpp;

// define the structure
struct xptr_data{
  SEXP xptr;
};

// a minimal function (user-defined)
// [[Rcpp::export]]
NumericVector timesTwo(NumericVector x) {
  return x * 2;
}

// pointer to function defined
typedef NumericVector (*funcPtr) (NumericVector y);

// [[Rcpp::export]]
XPtr<funcPtr> putFunPtrInXPtr() {

  XPtr<funcPtr> rhs_ptr(new funcPtr(&timesTwo), false); 
  return rhs_ptr;
}

// this function will be in the package
NumericVector call_by_xptr_struct(NumericVector y, void* user_data){

  struct xptr_data *my_rhs_ptr = (struct xptr_data*)user_data;
  SEXP xpsexp = (*my_rhs_ptr).xptr;

  // use function pointer to get the derivatives
  XPtr<funcPtr> rhs_xptr(xpsexp);
  funcPtr rhs_fun = *rhs_xptr;

  // use the function to calculate value of RHS ----
  return(rhs_fun(y));
}


// using xptr to evaluate function - this will be exported
// from the package
//[[Rcpp::export]]
NumericVector xptr_call_struct(NumericVector y, SEXP xpsexp){

  struct xptr_data my_xptr = {NULL};

  my_xptr.xptr = xpsexp;
  return call_by_xptr_struct(y, (void*)&my_xptr);
}

/*** R    
rhs_ptr <- putFunPtrInXPtr()

xptr_call_struct(c(1,2), rhs_ptr)
[1] 2 4
*/ 

什么不起作用,

如果函数定义在R我用Rcpp::Function直接导致整个 R 会话崩溃,

#include <Rcpp.h>
using namespace Rcpp;

// define the function based structure
struct func_data{
  Function func;
};

// processes the input function 
NumericVector call_by_func_struct(NumericVector y, void* user_data){

  struct func_data *my_rhs_fun = (struct func_data*)user_data;
  Function func = (*my_rhs_fun).func;

  return(func(y));
}

// this will be exported from the package
//[[Rcpp::export]]
NumericVector func_call_struct(NumericVector y, Function func){

  struct func_data my_func = {NULL};

  my_func.func = func;
  return call_by_func_struct(y, (void*)&my_func);
}

/*** R
timesThree <- function(y){

  y <- 3 * y
  y
}

*/

上面的代码编译得很好,但是当我调用该函数时func_call_struct(c(1,2), timesThree)),它会导致整个 R 会话崩溃。

有关原因的任何指导R崩溃以及如何输入定义的函数R会很有帮助的。

此外,有什么方法可以传递定义在的输入函数Rcpp (e.g., timesTwo上面)而不是他们的Xptr。我认为这对于最终用户来说不会那么混乱(因为他们不必生成函数指针),而不会牺牲随之而来的速度Rcpp.


它有效,如果你初始化结构体 https://stackoverflow.com/questions/31196102/note-personperson-is-implicitly-deleted-because-the-default-definition-wo使用可用的Function:

[...]
// this will be exported from the package
//[[Rcpp::export]]
NumericVector func_call_struct(NumericVector y, Function func){

  struct func_data my_func = {func};
  return call_by_func_struct(y, (void*)&my_func);
}

至于你的附加问题:我认为不使用外部指针就不可能在 R 中存储 C++ 函数指针。你不能提供一个辅助函数(可能是wrap())从函数指针创建外部指针?沿着这些思路:

#include <Rcpp.h>
using namespace Rcpp;

// define the structure
struct xptr_data{
  SEXP xptr;
};

// pointer to function defined
typedef NumericVector (*funcPtr) (NumericVector y);


// this function will be in the package
NumericVector call_by_xptr_struct(NumericVector y, void* user_data){

  struct xptr_data *my_rhs_ptr = (struct xptr_data*)user_data;
  SEXP xpsexp = (*my_rhs_ptr).xptr;

  // use function pointer to get the derivatives
  XPtr<funcPtr> rhs_xptr(xpsexp);
  funcPtr rhs_fun = *rhs_xptr;

  // use the function to calculate value of RHS ----
  return(rhs_fun(y));
}


// using xptr to evaluate function - this will be exported
// from the package
//[[Rcpp::export]]
NumericVector xptr_call_struct(NumericVector y, SEXP xpsexp){

  struct xptr_data my_xptr = {xpsexp};
  return call_by_xptr_struct(y, (void*)&my_xptr);
}


// function in package with only C++ API
XPtr<funcPtr> wrapFunPtr(funcPtr& f) {
  XPtr<funcPtr> rhs_ptr(&f, false); 
  return rhs_ptr;
}



// user-defined functions
NumericVector timesTwo(NumericVector x) {
  return x * 2;
}

// [[Rcpp::export]]
XPtr<funcPtr> putFunPtrInXPtr() {
  static funcPtr f = &timesTwo;
  return wrapFunPtr(f);
}



/*** R    
rhs_ptr <- putFunPtrInXPtr()

xptr_call_struct(c(1,2), rhs_ptr)
*/ 

用户将提供最后两个函数。对于 C++11,这可以简化如下:

// [[Rcpp::export]]
XPtr<funcPtr> putFunPtrInXPtr() {
  static funcPtr timesTwo{ [](NumericVector x) -> NumericVector { return x * 2; } };
  return wrapFunPtr(timesTwo); 
}

尽管在这种情况下使用可能就足够了

// [[Rcpp::export]]
XPtr<funcPtr> putFunPtrInXPtr() {
  static funcPtr timesTwo{ [](NumericVector x) -> NumericVector { return x * 2; } };
  XPtr<funcPtr> rhs_ptr(timesTwo, false); 
  return rhs_ptr;
}

无需wrapFunPtr在包裹中。用户必须提供一个函数,其中包括一些样板代码以及 lambda 表达式中的实际“内容”。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Xptr 和 Function 调用 Rcpp 函数 - 仅 xptr 情况有效 的相关文章

随机推荐

  • 如何让重力“底部”在 xml 中的可绘制对象上工作

    我有一个简单的目标 我想要我的 FrameLayout 上有一个浅灰色背景 下面有一条黑色分界线 仅在下面 而不是周围 到目前为止我有这个
  • System.getProperty("user.name") 返回 HOSTNAME 而不是当前记录的用户名

    Here System getProperty user name 返回 Windows Server 2008 计算机的主机名而不是当前登录的用户名 下面是我的代码 final String user System getProperty
  • PHP 删除另一个数组项(如果存在)[重复]

    这个问题在这里已经有答案了 我有 2 个对象数组 数组 A 和数组 B 如何检查数组 B 中的对象是否存在于数组 A 中 如果存在 则将其从数组 A 中删除 Example Array A id 1 name item1 id 2 name
  • 将 string 类型转换为 unsigned int 时出现故障

    我编写的 C 函数遇到了一个恼人的问题 该函数的目的是验证用户输入 该函数读取用户输入 验证它是否是数字 如果是 则验证它是否在 min max 范围内 当我使用无符号类型调用模板函数时 就会出现问题 例如size t 输入为负数 字符串流
  • 数组行为混乱[重复]

    这个问题在这里已经有答案了 在编码测试中 我最近遇到一个问题 要求我找出控制台中将打印什么内容 问题如下 我不明白下面的代码将如何被理解和执行 需要帮忙 var arr a b c d 1 2 3 console log arr 这个 ar
  • 如何开发像 Coffee Script 这样的编程语言?

    要开发像咖啡脚本这样的编程语言 我需要知道的初始要求是什么 它基本上有自己的语法 但在编译后会更改为另一种语言 我对此进行了谷歌搜索 但找不到正确的答案 使用基本语言指定您的语言形式语法 http en wikipedia org wiki
  • Qt C++ QString 到 QByteArray 转换

    我创建了一个加密 解密程序 加密时我将加密的 QByteArray 存储在文本文件中 当尝试解密时 我检索了它 然后将其放入解密方法中 问题是我需要一种将其转换为 QByteArray 的方法不改变格式 否则无法正确解密 我的意思是 如果该
  • 用于转换 pandas groupby 数据框的 Python lambda 函数语法

    这应该是一个非常简单的问题 我有两行代码 第一个有效 第二个给出以下错误 SyntaxError invalid syntax 这是两行代码 第一行 工作正常 对 off0 on1 1 的行进行计数 第二行尝试对 off0 on1 0 的行
  • Java Socket 创建需要更多时间

    我给了Socket soc new Socket host port 现在 当主机启动并处于运行状态时 套接字将立即创建 但是 当机器关闭或重新启动时 该行大约需要 40 秒才能响应 我尝试使用soc setSoTimeout timeou
  • HBase 作为 Web 应用程序后端

    任何人都可以建议将 HBase 作为基于 Web 的应用程序的主要数据源是否是一个好主意 我主要关心的是 HBase 对查询的响应时间 是否有可能实现亚秒级响应 编辑 有关应用程序本身的更多详细信息 数据量 约500GB文本数据 预计很快将
  • 如何生成不带绿色复选标记的签名 PDF

    我正在使用 iText 签署 PDF 我在签名中添加了图形 这是可行的 但是验证文档时显示的绿色复选标记 或黄色问号 会干扰我插入的图形 使最终结果看起来很难看 它要么显示在签名图形的上方或下方 但我无法让它消失 有谁知道如何解决这一问题
  • JMS 生产者中的错误:AMQ212054 目标地址被阻止

    我正在尝试使用 Spring Boot 2 1 1 RELEASE 连接到远程 Artemis 2 6 3 发送器 到目前为止 在我发现的所有示例中 发件人在尝试发送消息时都会挂起 例如here https grokonez com spr
  • I-码头或码头

    我有一个要在 Android 设备上托管的网络应用程序 我目前正在使用 android sdk 提供的模拟器 我的应用程序将同时提供静态和动态数据 我目前使用的是jetty版本6 1 22 我想问什么是更好的选择 1 Jetty 网络服务器
  • 配置多个下一个插件:withMDX、withBundleAnalyzer

    我开始了一个nextjs网站已经附带了顺风博客启动器withBundleAnalyzer在 next config js 中 我现在正在努力获得 mdx文件直接从页面工作 文档说我需要withMDX在我的 nextjs config 文件中
  • PHP反序列化问题

    为什么反序列化没有恢复我的数组 请参阅下面的代码 prints a 1 s 8 txn type s 32 recurring payment profile cancel echo item response prints nothing
  • Android:验证密码、确认密码并通过按钮传递字符串值

    我的注册页面中有密码 确认密码和性别等字段 密码编辑文本 确认密码编辑文本 性别 按钮01 按钮02 对于密码和一致密码 我想验证这两个字段 我的意思是两个字段的条目 字符串值 应该相同 如果两者相同 那么我只想将密码值传递到服务器 而不是
  • 如何重新启动 git/GitHub 项目?

    我已经在 GitHub 上托管的项目上工作了一段时间 然而 我现在决定以不同的方式重写我的应用程序 并从头开始 我重命名了旧的本地存储库并创建了一个新的 如何使用新存储库替换 GitHub 上托管的存储库 我真的不在乎我的旧历史和问题是否存
  • 设置嵌入式 h2 数据库的端口号

    I use h2内存数据库仅用于测试目的 默认端口似乎是8082 这导致我的测试在 Heroku 上失败 我想更改此端口号 我怎样才能做到这一点 到目前为止我所做的 我的本地计算机上似乎有一个文件 USER HOME h2 server p
  • 异步方法上的 C# 实体框架错误

    我已经看到了这一点 但我遇到了另一个问题 我有这个服务类用于管理 ASP NET 身份角色 public class RoleService IRoleService private readonly RoleManager
  • 使用 Xptr 和 Function 调用 Rcpp 函数 - 仅 xptr 情况有效

    我正在尝试开发一个包 其中我需要输入用户的函数 可以使用定义Rcpp or in R 将其发送到另一个函数 在包内 struct并在那里处理它 当我使用Rcpp Xptr 即函数指针 代码可以工作 但同样不起作用Rcpp Function