2016-02-10 7 views
8

私はnumpyとRの両方を使用するCコードをいくつか持っています。Windowsでは、Rから動的にロードできるDLLにMSVCをコンパイルし、しかし、私はそれをDebian上で動作させることはできません。Linux上でRとnumpyの両方を使用するCコードをコンパイル

私は、次の最小限っぽい例作成した問題を調査するために:

#include <Python.h> 
#include <Rinternals.h> 
#include <numpy/arrayobject.h> 

SEXP main() { 
    Py_Initialize(); 
    import_array(); 

    SEXP one = PROTECT(allocVector(INTSXP, 1)); 
    INTEGER(one)[0] = 1; 
    npy_intp dims[1] = {1}; 
    int data[1] = {1}; 
    PyObject *another = PyArray_SimpleNewFromData(1, dims, NPY_INT, data); 

    Rprintf("Hello, %d ", INTEGER(one)[0] + *(int*)PyArray_DATA(another)); 
    PyRun_SimpleString("print('worlds')"); 

    UNPROTECT(1); 
    return one; 
} 

私はRdll.lib

pexports R.dll > R.exp 
link /lib /def:R.exp /machine:x64 /out:Rdll.lib 
%R_HOME%\bin\x64\R.dllから作成された

cl /I "C:\Program Files\R\R-3.2.0\include" /I "C:\Python34\include" /I "C:\Python34\Lib\site-packages\numpy\core\include" /c hello.c 
link /dll /export:main hello.obj Rdll.lib C:/Python34/libs/python34.lib 

でそれをコンパイルすることができますが

そしてそれはRから使用することができる。

> dyn.load(paste0("hello", .Platform$dynlib.ext)) 
> .Call("main") 
Hello, 2 worlds 
[1] 1 

ただし、Iは

gcc -shared -fPIC -I/usr/share/R/include -I/usr/include/python2.6 -lpython2.6 -L/usr/lib64/R/lib -lR hello.c -o hello.so 

とのDebian上でコンパイル及びRからインポート次の処理が行われた場合、:

> dyn.load("hello.so") 
> .Call("main") 
Traceback (most recent call last): 
    File "/usr/lib/pymodules/python2.6/numpy/__init__.py", line 132, in <module> 
    import add_newdocs 
    File "/usr/lib/pymodules/python2.6/numpy/add_newdocs.py", line 9, in <module> 
    from lib import add_newdoc 
    File "/usr/lib/pymodules/python2.6/numpy/lib/__init__.py", line 4, in <module> 
    from type_check import * 
    File "/usr/lib/pymodules/python2.6/numpy/lib/type_check.py", line 8, in <module> 
    import numpy.core.numeric as _nx 
    File "/usr/lib/pymodules/python2.6/numpy/core/__init__.py", line 5, in <module> 
    import multiarray 
ImportError: /usr/lib/pymodules/python2.6/numpy/core/multiarray.so: undefined symbol: _Py_ZeroStruct 

*** caught segfault *** 
address 0x4, cause 'memory not mapped' 

numpyに関連するすべてがコメントアウトされていない限り、セグメンテーションフォルトが生成されます。 Rからの純粋なPythonとのやりとりはOKであるようです。しかし、import_array()と呼ばれるとすぐに、segfaultがあります。私は欲望のうち-I/usr/share/pyshared/numpy/core/include/を追加し、何も変わらなかった。最後

、Iは

gcc -I/usr/share/R/include -I/usr/include/python2.6 -lpython2.6 -L/usr/lib64/R/lib -lR hello.c -o hello 

で(前と同様、若干変更された)次のコードは同じDebianのマシン上

#include <Python.h> 
#include <Rinternals.h> 
#include <numpy/arrayobject.h> 

int main() { 
    char *localArgs[] = {"R", "--silent"}; 
    Rf_initEmbeddedR(2, localArgs); 
    Py_Initialize(); 
    import_array(); 

    SEXP one = PROTECT(allocVector(INTSXP, 1)); 
    INTEGER(one)[0] = 1; 
    npy_intp dims[1] = {1}; 
    int data[1] = {1}; 
    PyObject *another = PyArray_SimpleNewFromData(1, dims, NPY_INT, data); 

    Rprintf("Hello, %d ", INTEGER(one)[0] + *(int*)PyArray_DATA(another)); 
    PyRun_SimpleString("print('worlds')"); 

    UNPROTECT(1); 
} 

をコンパイルし

でそれを呼び出した場合
LD_LIBRARY_PATH=/usr/lib64/R/lib R_HOME=/usr/lib64/R ./hello 

it突然クラッシュせず、うまく動作し、期待通りに「こんにちは、2つの世界」を作り出します。

バージョンは次のとおりです。 のWindows:x64のためのコンパイラバージョン19.00.23506、Pythonの3.4.4、1.9.3 numpyの、R 3.2.0 のDebian:gccのバージョン4.4.5(対象:x68_64-linuxの - ヌー) 、Python 2.6.6、numpy 1.4.1、R 3.2.1

私は間違っていますか?

アップデート: gccとclangの両方でPython 3.2とPython 2.7の両方でUbuntuでテストされています。問題は解決しません。

答えて

0

のdlopenでlibpythonX.Y.soをロードすることです(実際のコードを持つだけでなく、この例で)機能するソリューション:それが必要とされる理由を

#include <Python.h> 
#include <Rinternals.h> 
#include <numpy/arrayobject.h> 

#ifndef _WIN32 
#include <dlfcn.h> 
#endif 

SEXP main() { 
#ifndef _WIN32 
    dlopen("libpython2.6.so", RTLD_NOW | RTLD_GLOBAL); 
#endif 
    Py_Initialize(); 
    import_array(); 

    SEXP one = PROTECT(allocVector(INTSXP, 1)); 
    INTEGER(one)[0] = 1; 
    npy_intp dims[1] = {1}; 
    int data[1] = {1}; 
    PyObject *another = PyArray_SimpleNewFromData(1, dims, NPY_INT, data); 

    Rprintf("Hello, %d ", INTEGER(one)[0] + *(int*)PyArray_DATA(another)); 
    PyRun_SimpleString("print('worlds')"); 

    UNPROTECT(1); 
    return one; 
} 

私は、しかし、完全には理解していません。