在过去的几年中,我们创建了一个使用 X25 协议的程序。它是用 C 语言制作的,可以在装有 Solaris 5.9 的 Sun-Fire 机器上正常工作。最近,我们正在同一台机器上使用 java 6,我们正在尝试调整 C 中的旧程序以通过 jni 使用 java。所以我对旧的 C 程序做了一些修改,并创建了一个名为 x25lib.so
但是我在使用 jni 和 X25 时发现了一个运行时问题:当通过 jni 从 java 调用 C 函数时,C 代码的工作方式与从另一个 C 程序调用时不同。
具体来说,使用jni,共享库中的C代码可以正常工作,直到调用系统调用connect()
,然后返回-1,
但是从另一个 C 程序调用我的共享库的相同 C 代码返回 0(确定)
在这两种情况下,共享库中的 C 代码都没有接收外部参数,因此条件相同,我不明白从 java 加载我的“x25lib.so”共享库是否有一点差异,导致connect()
C 失败。
使用 java 中的“truss”命令我发现了错误:
/2: connect(5, 0xFD878B75, 112, 1) Err#22 EINVAL
相同,但从另一个 C 程序调用共享库:
connect(4, 0xFFBFE794, 114, 1) = 0
所以它只适用于纯C,
在 solaris 5.9 中使用 jni 和 X25 是否还有其他考虑?
重要提示:共享库中的 C 代码在这两种情况下都是相同的。
编译时间:
一个。创造x25lib.so
cc -w -fd -G -Kpic subs.o -L/opt/SUNWconn/lib -R/opt/SUNWconn/lib -lsockx25
-lsocket -lnsl -I"/SDK/jdk/include/" -I"/SDK/jdk/include/solaris/"
-o x25lib.so -h x25lib.so x25jni.c
湾。使用该共享库创建测试 C 程序:
cc -w x25lib.so -o x25test x25test.c
where `x25test.c` contains:
#include <stdio.h>
main()
{
java_x25();
}
C。使用java:
public class X25 {
static {
System.load("/home/x25lib.so");
}
public native void ejecutaComando();
}
public class TestX25 {
public static void main(String ... args) {
X25 x25 = new X25();
x25.ejecutaComando();
}
}
然后在 C 代码共享库中:
/*
* Class: X25
* Method: ejecutaComando
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_X25_ejecutaComando
(JNIEnv *env, jobject obj)
{
java_x25();
}
所以最后两个程序(java y C)在共享库中调用完全相同的C代码:
java_x25()
没有参数,所以执行相同的代码。
为什么从C调用时工作正常,但从java调用时失败?
感谢您的任何建议。