我需要使用* .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
}
答案 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
现在一切正常。