如何包装在R中使用的第三方DLL?

时间:2018-10-30 09:04:17

标签: c++ c r

我需要使用* .h和* .dll文件附带的现有第三方API将数据加载到R中。dll提供的函数不能直接调用,因此我需要将它们包装起来才能调用为了使自己熟悉,我制作了一个小示例dll(基于MINGW页面here上的HOWTO,我将文件的源代码放在了文章的结尾)。其中只有一个函数可以将整数输入加倍。我可以很好地编译dll,也可以在exe文件中使用它,因此它可以正常工作。这是在Windows 10上。

我不确定如何在R中正确使用它。我创建了一个程序包(名为testwithdll2),并将头文件和dll以及包装函数一起放置在“ src”中。当我尝试编译程序包时,出现以下未定义引用的错误消息:

C:/Rtools/mingw_64/bin/gcc  -I"C:/PROGRA~1/R/R-35~1.1/include" -DNDEBUG
-O2 -Wall  -std=gnu99 -mtune=generic -c mydouble_c.c -o mydouble_c.o
C:/Rtools/mingw_64/bin/gcc -shared -s -static-libgcc -o testwithdll2.dll
tmp.def mydouble_c.o -LC:/PROGRA~1/R/R-35~1.1/bin/x64 -lR
mydouble_c.o:mydouble_c.c:(.text+0xc): undefined reference to `__imp_timestwo'
collect2.exe: error: ld returned 1 exit status

任何可能出现问题的指针都将受到赞赏。

example_dll.h:

#ifndef EXAMPLE_DLL_H
#define EXAMPLE_DLL_H

#ifdef __cplusplus
extern "C" {
#endif

#ifdef BUILDING_EXAMPLE_DLL
#define EXAMPLE_DLL __declspec(dllexport)
#else
#define EXAMPLE_DLL __declspec(dllimport)
#endif

int EXAMPLE_DLL timestwo(int x);

#ifdef __cplusplus
}
#endif


#endif  // EXAMPLE_DLL_H

example_dll.cpp:

#include <stdio.h>
#include "example_dll.h"

int timestwo(int x)
{
        return 2 * x;
}

mydouble.c(在r包的src文件夹中):

#include "example_dll.h"
void mydouble(int* a){
  *a = timestwo(*a);
}

timestwo.R(包装函数,在R文件夹中):

#' @useDynLib testwithdll2 mydouble
#' @export
timestwo <- function(n){
  .C("mydouble",n )
  n
}

1 个答案:

答案 0 :(得分:0)

我知道该怎么办。 必须使用带有以下行的makevars文件:

MAKEVARS:

First min(First first, Args... args) 

在调用testwithdll2.dll之前,还必须将useDynlib调用添加到命名空间中的example_dll.dll。这也意味着PKG_CPPFLAGS= -I. PKG_LIBS= -L. -lexample_dll 调用需要指定.C参数,因此我不得不将r包装器更改为:

timestwo.R

PACKAGE

现在一切正常。