会计考友 发表于 2012-8-4 12:44:44

JAVA认证:Java中调用dll动态库简洁方法

解压JNative-1.3.2.zip 获得三个文件,分袂是:JNativeCpp.dll,libJNativeCpp.so,JNative.jar 。JNativeCpp.dll Windows下用的,拷到windows / system32目录下;
libJNativeCpp.so Linux下使用的;
JNative.jar 这是一个扩展包,加载到你的轨范中就可以。
一个简单例子
import org.xvolks.jnative.JNative;
import org.xvolks.jnative.Type;
import org.xvolks.jnative.exceptions.NativeException;
public class JNativeTest {
public static final int messageBox(int parentHandle, String message,
String caption, int buttons){// throws NativeException, IllegalAccessException {
JNative n = null;
try {
n = new JNative(“User32.dll”, “MessageBoxA”); //“.dll”不用也可以, 常量DLL_NAME的值为User32.dll
// 机关JNative时完成装载User32.dll,而且定位MessageBoxA体例
n.setRetVal(Type.INT); // 指定返回参数的类型
int i = 0;
n.setParameter(i++, Type.INT, “” + parentHandle);
n.setParameter(i++, Type.STRING, message);
n.setParameter(i++, Type.STRING, caption);
n.setParameter(i++, Type.INT, “” + buttons); // 指定位置上的参数类型和值
n.invoke(); // 挪用体例
return Integer.parseInt(n.getRetVal());
}
catch(Exception ex){
ex.printStackTrace();
}
finally {
if (n != null)
try {
n.dispose();
} catch (NativeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} // 记得释放


}
return 0;
}
public static void main(String[] args) throws NativeException, IllegalAccessException{
JNativeTest.messageBox(100,“这是使用jnative操练”, “jnativetest”, 1);
}
}
关于linux下编译 C代码部门声名:
对于linux分歧版本,可能会导致libJNativeCpp.so分歧
原带的libJNativeCpp.so 是在glic2.4下编译的
为了顺应glic2.3的情形,从头编译了libJNativeCpp.so,在for gcc3.4.6 glibc 2.3下。
编译法子:
在JNative-1.3.2-src\JNativeCpp\Release目录下
1、备份calls.o和 asm_io.o这两个Object文件
2、make clean
3、恢复到当前目录calls.o和 asm_io.o这两个Object文件
4、make
今朝已经改削了Release目录下的makefile和subdir.mk文件,使得在make clean的时辰不删除calls.o和 asm_io.o两个文件
附:linux 动态库搜索路径:
export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
makefile 文件
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
-include 。./makefile.init
RM := rm -rf
# All of the sources participating in the build are defined here
-include sources.mk
-include subdir.mk
-include objects.mk
ifneq ($(MAKECMDGOALS),clean)
ifneq ($(strip $(C++_DEPS)),)
-include $(C++_DEPS)
endif
ifneq ($(strip $(CC_DEPS)),)
-include $(CC_DEPS)
endif
ifneq ($(strip $(C_DEPS)),)
-include $(C_DEPS)
endif


ifneq ($(strip $(CPP_DEPS)),)
-include $(CPP_DEPS)
endif
ifneq ($(strip $(CXX_DEPS)),)
-include $(CXX_DEPS)
endif
ifneq ($(strip $(C_UPPER_DEPS)),)
-include $(C_UPPER_DEPS)
endif
endif
-include 。./makefile.defs
# Add inputs and outputs from these tool invocations to the build variables
# All Target
all: libJNativeCpp.so
# Tool invocations
libJNativeCpp.so: $(OBJS) $(OBJS_ASM) $(USER_OBJS)
@echo ‘’Building target: $@‘’
@echo ‘’Invoking: GCC C++ Linker‘’
g++ -shared -o“libJNativeCpp.so” $(OBJS) $(OBJS_ASM) $(USER_OBJS) $(LIBS)
@echo ‘’Finished building target: $@‘’
@echo ‘’ ‘’
# Other Targets
clean:
-$(RM) $(OBJS)$(C++_DEPS)$(CC_DEPS)$(C_DEPS)$(CPP_DEPS)$(LIBRARIES)$(CXX_DEPS)$(C_UPPER_DEPS) libJNativeCpp.so
-@echo ‘’ ‘’
.PHONY: all clean dependents
.SECONDARY:
-include 。./makefile.targets
subdir.mk 文件
################################################################################
# Automatically-generated file. Do not edit!
################################################################################
# Add inputs and outputs from these tool invocations to the build variables
C_SRCS +=
。./jni_util.c
。./mem.c
CPP_SRCS +=
。./CallBack.cpp
。./WindowProcUtil.cpp

。./org_xvolks_jnative_JNative.cpp
ASM_SRCS +=
。./asm_io.asm
。./calls.asm
OBJS +=
。/CallBack.o
。/WindowProcUtil.o
。/jni_util.o
。/mem.o
。/org_xvolks_jnative_JNative.o
OBJS_ASM +=
。/asm_io.o
。/calls.o
C_DEPS +=
。/jni_util.d
。/mem.d
CPP_DEPS +=
。/CallBack.d
。/WindowProcUtil.d
。/org_xvolks_jnative_JNative.d
# Each subdirectory must supply rules for building sources it contributes
%.o: 。./%.cpp
@echo ‘’Building file: $《‘’
@echo ‘’Invoking: GCC C++ Compiler‘’
g++ -I“/home/gongjan/jdk1.5.0_08/include/” -I“/home/gongjan/jdk1.5.0_08/include/linux” -O3 -Wall -c -fmessage-length=0 -Wl,--add-stdcall-alias -MMD -MP -MF“$(@:%.o=%.d)” -MT“$(@:%.o=%.d)” -o“$@” “$《”
@echo ‘’Finished building: $《‘’
@echo ‘’ ‘’
%.o: 。./%.asm
@echo ‘’Building file: $《‘’
@echo ‘’Invoking: GCC Assembler‘’
nasm -f elf -d ELF_TYPE -o“$@” “$《”
@echo ‘’Finished building: $《‘’
@echo ‘’ ‘’
%.o: 。./%.c
@echo ‘’Building file: $《‘’
@echo ‘’Invoking: GCC C Compiler‘’
gcc -I“/home/gongjan/jdk1.5.0_08/include/linux” -I“/home/gongjan/jdk1.5.0_08/include/” -O3 -Wall -c -fmessage-length=0 -Wl,--add-stdcall-alias -MMD -MP -MF“$(@:%.o=%.d)” -MT“$(@:%.o=%.d)” -o“$@” “$《”
@echo ‘’Finished building: $《‘’
@echo ‘’ ‘’

  valuesa/value
  /property
  property name="password"
  value/value
  /property
  /bean
  /beans
  测试类:
  import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Test }
  和膳缦沔的 TestTemplate 类对比, 就会发现 new DriverManagerDataSource() 这个过程不用我们写了, 运行的时辰会发现一切都执行的好好的, 也就是常说的 ExecuteAStatement 的 dataSource 这个属性被注入了。
  那么这个过程到底该若何理解呢? Spring 是一个对象池, 可以简化为一个 Map, 存多个主键和对象的映射。 那么 Spring 运行的过程中, 会按照 beans.xml 一步步进行需要的解析工作:
  Map springEngine = new HashMap();
  OK, 解析到了
  bean id="userDAO" , 发现 bean 界说, 那就新建一个实例存到对象池里吧, 主键就是 userDAO, 值就是对象:
  ExecuteAStatement bean1 = new ExecuteAStatement();
  springEngine.put("userDAO", bean1);
  再往下执行, 发现 property 界说:
  property name="dataSource"
  到了这里, 就知道应该挪用 bean1.setDataSource(DataSource) 体例了。 可以接着执行, 发现
  ref bean="myDataSource" /, 哦, 这个体例的参数还没有呢, 是个 bean 的引用, 好了, 要挪用这个体例, 仍是先 new 一个名字为 myDataSource 的 bean2 吧。 就跳到下面寻找 myDataSource 的界说, 找到了:
  bean id="myDataSource"property name="driverClassName"valueorg.hsqldb.jdbcDriver/value/propertyproperty name="url"valuejdbc:hsqldb:hsql://localhost:/value/propertyproperty name="username"valuesa/value/propertyproperty name="password"value/value/property /bean
  像以前一样, 先实例化这个类, 然后看到 property 神色就挪用对应的 setXxx() 这样的体例, 相当于下面一段代码:
  // 新建一个数据源对象DriverManagerDataSource bean2 = new DriverManagerDataSource;bean2.setDriverClassName;bean2.setUrl;bean2.setUsername;bean2.setPassword;
  不是还有个 bean 的 id 名字为 myDataSource 嘛, 那就把它存到对象池琅缦沔:
  springEngine.put("myDataSource", bean2);
  好了, 最后就是把他们两个联系关系起来了, 经由过程 ref 里指定的 bean id 名来联系关系起来:
  // 省略类型转换的代码
  springEngine.get("userDAO")。setDataSource(springEngine.get("myDataSource"));
  最后返回给用户的就是一个对象池(一个 Map)了, 所以别人挪用的时辰, 就发现 springEngine.get("userDAO") 回来的类的 dataSource 属性已经被实例化过了, 这些都是 Spring 幕后工作的代码, 经由过程反射机制来实现。
  所以最后写代码挪用:
  context.getBean("userDAO") 的时辰, 获得的是 ExecuteAStatement, 这时辰还有一个 myDataSource, 也可以被挪用:
  context.getBean("myDataSource"), 获得的是 DriverManagerDataSource.
页: [1]
查看完整版本: JAVA认证:Java中调用dll动态库简洁方法