c - 如何从 R session 中更改 C 宏变量(预处理器定义指令)?

标签 c r system directive

问题

  1. 使用 system()shell() 从 R session 内部编译共享库然后动态加载它们是否是一种不好的做法?
  2. 有没有“更好”的方法(比下面的代码)根据来自 R session 的用户输入更改 C 源文件中宏变量的值?

背景

目标

在 R session 中,我想创建一个函数

  1. 更改模板 C 源文件中宏变量的值,
  2. 给编辑后的源文件一个新的名字,
  3. 编译新程序的共享库,并且
  4. 将新共享库动态加载到当前 R session 中

调用模板 C 源文件 template.tmp 并让它看起来像这样:

...
#define VAR
...

(我不打算实际编译 template.tmp,因此 .tmp 文件扩展名。我只是将它用作模板来创建其他源文件,其中只有 #define 指令改变了。)

下面是我为执行上述步骤而创建的 R 函数。为简单起见,我删除了声明正确路径名或向 Windows 和其他类似 Unix 系统添加可移植性的代码行。

myfunc <- function(val){
  # create commands for system()
  subst_cmd <- paste0("sed 's/define VAR/define VAR ", val, "/' template.tmp > newprog.c")
  shlib_cmd <- paste0("R CMD SHLIB newprog.c")

  # submit commands to system()
  system(subst_cmd)
  system(shlib_cmd)

  # dynamically load shared library
  dyn.load(newprog.so)
}

因此,myfunc(12345) 将使用以下行创建一个新的 C 源文件,并将其编译为共享库并动态加载到当前 R session 中。

...
#define VAR 12345
...

动机

我有一个函数,速度非常重要,因为该函数可能被调用数千次。与使用 #define 预处理器指令相比,将值传递给 C 源文件中的函数会大大降低速度。我的想法是如何在 R 中编辑文件然后编译它并将其加载到 R session 中。但我不知道这是否是一种好的做法,或者是否有另一种方法可以完成同样的任务。当我远程进入登录节点具有编译功能但计算节点没有的计算机集群时,我已经遇到了一个问题。

最佳答案

免责声明:我对 R 了解不多。我是根据我使用 C 共享库的经验来回答这个问题的。

Is it bad practice to compile shared libraries from inside an R session using system() or shell() then dynamically load them?

是的,这不是一个好的做法。正如您所说,每次更改文件和编译可能需要 1000 秒的时间,这不是一个好的选择。

Is there a "better" way (than the code below) to change the value of a macro variable in a C source file based on user input from an R session?

如果唯一的要求是更改宏的值,那么为什么不将其转换为变量并在调用动态加载库中的函数时传递该变量?

考虑以下示例:(以下代码用于动态库)

foo.h

#ifndef foo_h__
#define foo_h__

extern void foo(int var);

#endif  // foo_h__

foo.c

#include <stdio.h>
int global_var;

void foo(int var)
{
    global_var= var;
}

通过将 var 的所需值传递给 foo 函数,从 R 调用上述函数。 (我希望你知道如何做到这一点)

I don't plan on actually compiling template.tmp, hence the .tmp file extension. I merely use it as a template to create other source files where only the #define directive changes.

我建议不要这样做。即使你有不止一个这样的宏,你仍然可以使用上面的逻辑来处理它。我的建议是编译库一次,然后调用初始化函数(上例中的 foo)将所需的值传递给它。这也将避免多次加载库,从而提高效率。这比您当前所做的更好,并且易于维护和记录。

如果您关心速度和效率,文件操作本来就很慢。您的程序可能有一天会变大,因此为每个函数调用编译它会进一步增加执行延迟。每次都编译库是个坏主意。

关于c - 如何从 R session 中更改 C 宏变量(预处理器定义指令)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20662944/

相关文章:

mysql - 酒店预订系统数据库架构

c++ - 从非托管 C 程序在 Windows 系统托盘图标上写入文本时如何保持透明度

c - 指向结构体的指针的格式说明符

将 char 数组中的十六进制地址转换为 uint8_t

R包kernlab安装问题

r - h2o.Ensemble 中出现错误

c - printf 没有按预期工作。有人可以解释输出吗?

C - 读取文件并将内容写入数组,一次一个字符

r - 在数值向量的每对值之间添加序列

c++ - 如何在C++中并行执行系统命令