好像只能如此了:照java class 生成的 .h文件的规定来写。
要不只能按COM方式来调用。
要不只能按COM方式来调用。
解决方案 »
- 怎么理解arraylist<hashmap<string,string>>
- 如何统计垃圾回收对象
- 一个简单的JAVA算法问题
- 请教关于正则表达式的用法
- jsp访问javaBean是出错帮帮忙谢谢!
- 掌握了java的基本语法之后,怎样继续学下去?
- 刚学java不会的问题,求救
- war文件发布后运行错误
- 为什么在jbuilder中找不到javax.xml这个package
- 使用TYPE 4 JDBC ——MySQL Connector/J 3.0 连接MYSQL数据库,无论中文、英文都可以插入,但均为乱码!!(急啊!!!~~~~~~~~~~~~~~~我
- 产生异常的原因?
- 请问如何判断一个站点是否支持断点续传!
新的dll按照jni的规则定义好给java调用的方法看thinking in java说的:
为实现JNI固有方法,最简单的方法就是在一个Java类里编写固有方法的原型,编译那个类,再通过javah运行.class文件。但假若我们已有一个大型的、早已存在的代码库,而且想从Java里调用它们,此时又该如何是好呢?不可将DLL中的所有函数更名,使其符合JNI命名规则,这种方案是不可行的。最好的方法是在原来的代码库“外面”写一个封装DLL。Java代码会调用新DLL里的函数,后者再调用原始的DLL函数。这个方法并非仅仅是一种解决方案;大多数情况下,我们甚至必须这样做,因为必须面向对象引用调用JNI函数,否则无法使用它们。
你会不会用C写代码调用dll啊?
那就得了,把调用的方法名字写成
JNIEXPORT void JNICALL
Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj){
//这里调用dll
}
Java_类名_方法名这个模式
http://java.sun.com/docs/books/tutorial/native1.1/stepbystep/index.html
就知道很清楚了:
流程是这样:
1.首先的有.dll的.h文件既API说明
2.写java代码你的方法应是调用本地方法的如:
...
//包装本地方法的java方法
void foo()
{
nativeFoo();
}
//声明本地方法的调用方法
native void nativeFoo();
...
3.编译上面的.java文件
会生成.class文件
4.用javah yourclasssname生成jni的头文件*.h
5.建立一个c/c++的工程(DLL)实现你的头文件的方法
6.编译后生成yourcppname.dll
7.把yourcppname.dll考到classpath路径下在2.步的你的.java类中加入
static
{
System.out.loadLibrary("yourcppname");
}后重新编译
8.执行重新编译后的.class......OK!
应是:System.loadLibrary("yourcppname");
5.的补充yourname.cpp
里是关键#include javah生成的头文件
...
***_***_nativeFoo()//java代码的package会生成很长的前缀(由javah自动生成,你从java生成的头文件copy来就行)
{
//在这里调用打印机的api
//
}...附:对于程序员来说,语言是工具,关键是思想!
{
private native void Print_Proxy();
static
{
try
{
System.loadLibrary("dllName");//你生成的dll的名字
}
catch(SecurityException e)
{
System.err.println("load failed");
}
} public void Print_Java(String[] version)
{
Print_Proxy();
}
}
javac testDll.java
javah -jni testDll
cl -I JAVA_HOME\include -I JAVA_HOME\include\win32 -LD testDll.c -FedllName.dlltestDll.c
#include <stdio.h>
#include <windows.h>
#include "softCertProxy.h"typedef UINT (CALLBACK* PRINT_DLL)(char *);
JNIEXPORT jint JNICALL Java_testDll_Print_1Proxy
(JNIEnv * jEnv, jobject this)
{
HINSTANCE hDLL;
PRINT_DLL Print_Dll;
hDLL =LoadLibrary("Dll");//你要调用的dll
Print_Dll =(PRINT_DLL)GetProcAddress(hDLL,"print");//调用dll里的方法名
if (!Pring_Dll)
{
// handle the error
FreeLibrary(hDLL);
printf("dll link failed\n");
return flag;
}
else
{
//处理函数,具体看api,jni.h
}
}
我是假定你的dll里有print()方法。
public class softCertProxy
{
private native int Crypt_Get_Version_Proxy(String[] version); static
{
try
{
System.loadLibrary("soft_cert_proxy");
}
catch(SecurityException e)
{
System.err.println("load failed");
}
} //获得软件的版本号,该版本为2.0
public int Crypt_Get_Version_Java(String[] version)
{
int flag=1;
if (Crypt_Get_Version_Proxy(version) ==0)
{
System.out.println("The currently version is "+(String)version[0]);
flag =0;
}
else
System.out.println("Get version failed"); return flag;
}
}softCertProxy.c
#include <stdio.h>
#include <windows.h>
#include "softCertProxy.h"typedef UINT (CALLBACK* CRYPT_GET_VERSION_DLL)(char *);JNIEXPORT jint JNICALL Java_softCertProxy_Crypt_1Get_1Version_1Proxy
(JNIEnv * jEnv, jobject this, jobjectArray jversion)
{
HINSTANCE hDLL;
CRYPT_GET_VERSION_DLL Crypt_Get_Version_Dll;
char* version="";
int flag =1;
jstring string;
hDLL =LoadLibrary("soft_cert");
Crypt_Get_Version_Dll =(CRYPT_GET_VERSION_DLL)GetProcAddress(hDLL,"Crypt_Get_Version");
if (!Crypt_Get_Version_Dll)
{
// handle the error
FreeLibrary(hDLL);
printf("dll link failed\n");
return flag;
}
else
{
// call the function
if(Crypt_Get_Version_Dll(version) ==0)
{
flag =0;
(*jEnv)->NewObjectArray(jEnv, 1, (*jEnv)->FindClass(jEnv, "java/lang/String"), 0);
string = (*jEnv)->NewStringUTF(jEnv, (const char*)version);
(*jEnv)->SetObjectArrayElement(jEnv, jversion, 0, string);
} return flag;
}
} 假设你所要调用的dll名称是soft_cert.dll,有方法Crypt_Get_Version(char*);
现在生成soft_Cert_Proxy.dll调用原来的soft_cert.dll
这个小例子,你自己看看吧,API在j2sdk\include\jni.h执行以下三条命令,生成soft_Cert_Proxy.dll
javac softCertProxy.java
javah -jni softCertProxy
cl -I JAVA_HOME\include -I JAVA_HOME\include\win32 -LD softCertProxy.c -Fesoft_Cert_Proxy.dll