0

我有一个小问题。我正在尝试编译一个与 C 程序接口的 Java 程序,然后进一步与 FORTRAN 77 程序接口。基本上,Java,通过 JNI,使用使用 LAPACK(FORTRAN 版本)的 C 程序

C 程序本身运行良好,可以与 FORTRAN 77 程序进行接口,但是当我在 Java 中运行测试程序时,Fortran 和 C 之间的链接被破坏了。

我像这样编译C程序:

gcc -c -fPIC -I/usr/lib/jvm/java-6-openjdk/include -I/usr/lib/jvm/java-6-openjdk/include/linux -llapack -lblas -lm Optibox.c
gcc -shared -o libOptibox.so Optibox.o
LD_LIBRARY_PATH=./:${LD_LIBRARY_PATH} java Optibox

它返回错误:

java: symbol lookup error: /home/christian/workspace/testJNI4/libOptibox.so: undefined symbol: dsytrf_

由于这段代码而发挥作用:

static long dsytrf(char UPLO, long N, double* A, long LDA, long* IPIV, double* WORK, long LWORK)
{
    extern void dsytrf_(char* UPLOp, long* Np, double* A, long* LDAp, long* IPIV, double* WORK, long* LWORKp, long* infop);
    long info;
    dsytrf_(&UPLO, &N, A, &LDA, IPIV, WORK, &LWORK, &info);
    return info;
}

如果我只是简单地制作一个 C 程序来测试这个函数,这个函数就可以正常工作,但是在使用 Java 时,LAPACK 不再链接。

所以我想问题是:如何在这种情况下正确地使 Java 编译器链接?

编辑:我至少现在找到了解决方案。我将链接器语句更改为也链接到 BLAS、LAPACK 和 MATRIX 库本身。这似乎完全解决了这个问题,但我不相信它的优雅。我将尝试 Idav1s 给出的库路径建议。

gcc -shared -o libOptibox.so Optibox.o liblapack.so libblas.so libm.so

这要求我在 /usr/lib 中找到库并将它们复制到我的编译目录,但至少它可以工作!

4

2 回答 2

0

您需要将 LAPACK 和 blas 库添加到java.library.path

java -Djava.library.path=/usr/lib/lapack:<other paths> Optibox

添加它们LD_LIBRARY_PATH有时是不够的。

编辑:您的链接声明也不正确。它应该是:

gcc -shared -fPIC -o libOptibox.so Optibox.o -llapack -lblas -lm

链接器标志在构建时无关紧要Optibox.o。该libOptibox.so库需要其他库。否则它永远不会在加载时找到它们。

于 2012-05-23T20:07:11.297 回答
0

这确实属于评论,而不是答案,但我找不到评论按钮!所以无论如何,这来自 gcc 手册页,重新:“-shared”标志:“生成一个可以链接的共享对象......对于可预测的结果,您还必须指定用于指定此选项时生成代码(-fpic、-fPIC 或模型子选项)。”

您的 gcc 链接语句中没有“-fPIC”。那就是我要开始的地方。(实际上,我真正开始的地方是跳到任何希望你编写这些糟糕代码的人的办公桌上,对他们大喊大叫,直到他们改变主意。)

于 2012-05-23T20:07:27.600 回答