2012-01-04 142 views
0

我试图让我的SWIG实现在Windows XP(32位)机器上工作。我的test.java能够加载SWIG共享库DLL(System.loadLibrary(“TestJni”)),但当我试图调用我使用SWIG公开的任何C函数时,它会抛出下面的异常。我正在寻找一些调试技巧。我使用Makefile创建了使用32位Linux的共享库dll。也许在SWIG共享库dll的创建中出现了一些问题。我可以让它在Linux上工作(对Makefile有一些Linux特定的更改)。有任何想法吗?在Windows XP上无法调用使用DLL的本地SWIG方法

例外:

Exception in thread "main" java.lang.UnsatisfiedLinkError: com.test.jni.SampleJNI.setLogLevel(I)V 
     at com.test.jni.SampleJNI.setLogLevel(Native Method) 
     at com.test.jni.Sample.setLogLevel(Unknown Source) 
     at com.test.jni.Example.setLogLevel(Unknown Source) 
     at com.test.jni.Example.main(Unknown Source) 

生成文件创建该SWIG共享库DLL:

CMODE= 

SWIG = swig 
PREFIX=/test/mingw/mingw32/bin/i386-mingw32- 
CC = $(PREFIX)gcc 
LD = $(CC) 

OBJ_DIR = obj 
AUTOGEN_DIR = ../src/java 
PACKAGE_DIR = $(AUTOGEN_DIR)/com/test/jni 

PACKAGE = com.test.jni 

INCLUDES = -I$(HEADER_FILES_DIR) # env var that points to a dir with all the .h files 

LIB_INCLUDES = -L$(C_API_DIR)/lib # env var that points to a dir with the C libraries (dlls) 

LIBS = -lMainApi \ # MainApi.dll 
     -lm 

DIRS = $(PACKAGE_DIR) $(DIST_DIR) $(OBJ_DIR) $(AUTOGEN_DIR) # DIST_DIR is passed in 

CFLAGS = $(CMODE) -Wall -fpic $(INCLUDES) -O0 -g3 
SFLAGS = -java $(INCLUDES) -package $(PACKAGE) -outdir $(PACKAGE_DIR) 
LDFLAGS = -shared $(LIB_INCLUDES) $(LIBS) -leay32 -lws2_32 -lrpcrt4 

OBJECTS = $(OBJ_DIR)/test_wrap.o 
TARGET = $(LIB_DIR)/SampleJni.dll 

all: $(DIRS) $(TARGET) 

%_wrap.c: %.i 
    $(SWIG) $(SFLAGS) $< 

$(OBJ_DIR)/%.o: %.c 
    $(CC) $(CFLAGS) -c $< -o $@ 

$(TARGET): $(OBJECTS) 
    $(LD) $(OBJECTS) $(LDFLAGS) -o [email protected] 

$(DIRS): 
    mkdir -p [email protected] 

clean: 
    rm -rf $(TARGET) $(PACKAGE_DIR)/* $(TARGET) $(AUTOGEN_DIR) $(OBJ_DIR) 

编译输出:

[exec] /test/mingw/mingw32/bin/i386-mingw32-gcc obj/ewapi_wrap.o -shared -L/test/backup/jni/lib -lMainApi -lm -leay32 -lws2_32 -lrpcrt4 -o /test/backup/jni/lib/SampleJni.dll 
[exec] i386-mingw32-gcc: --kill-at: linker input file unused because linking not done 
[exec] rm ewapi_wrap.c 

回答

0
  1. 这很可能是您对Mingw32 dll的依赖,您在PATH中没有它。请咨询dependency walker并确保您的PATH中包含这些DLL。

  2. 您需要更改编译器标志。我认为你错过了以下选项:

    -D_JNI_IMPLEMENTATION_ -Wl,--kill-at

+0

感谢您的回复。我确实安装了MinGW,并将MinGW/bin放在路径上。我没有看到安装包中的任何DLL,只是exe文件。我以为MinGW只是为了编译? – c12 2012-01-04 18:18:08

+0

我在共享库JNI DLL上运行了依赖关系的步行者,唯一被标记的是MSJAVA.DLL缺失。根据http://www.dependencywalker.com/help/html/faq.htm,我认为这可以被忽略... – c12 2012-01-04 22:46:40

+0

我添加了MSJAVA.dll,现在MPR.dll被标记为警告:at由于延迟加载相关模块中缺少导出功能,因此至少有一个模块具有未解析的导入。根据我上面添加的链接,这似乎也可以,但不是100%确定的。 – c12 2012-01-04 22:52:48

0

我遗漏了从CFLAGS(编译)具有的jdk的jni.h和jni_md.h头文件的Java目录包括在Makefile中。一旦我将这些添加到Makefile中,我就可以通过JNI方法调用从java到c的通信。