求助:通过JNI在C中调用java c当然可用tc和vc++的win32编译器了至于怎么调,我也还不知道 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 会问c用什么编译器这种问题,你可能不会c/c++吧。写JNI必需要熟悉c/c++的,想写JNI,现学c/c++吧。 我用了tc,vc,编译的时候老出问题,而且那个错误很奇怪,怎么也编译不通过,请各位高手能针对tc,vc分别给个你们自己编译过的源码,好吗? 我用java调用c成功了,可是c调用java怎么也不行。我学过c/c++,可是JNI对java调c支持的较好一些啊,能不能留下你们联系方式 小弟在此感谢了 // test.cpp : Defines the entry point for the DLL application.//#include "stdafx.h"#include <windows.h> #include <jni.h> #include <string> using std::string; BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ){ return TRUE;}void vShowError(string sErrorMessage); void vShowLastError(string sErrorMessage); void vDestroyVM(JNIEnv *env, JavaVM *jvm); void vAddOption(string& sName); JavaVMOption* vm_options; int mctOptions = 0; int mctOptionCapacity = 0; //boolean GetApplicationHome(char *buf, jint sz); typedef jint (CALLBACK *CreateJavaVM)(JavaVM **pvm, JNIEnv **penv, void *args); //int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){ extern "C"_declspec(dllexport)int write(char *filename){ MessageBox(NULL, "欢迎使用", "welcome", MB_OK); JNIEnv *env; JavaVM *jvm; jint jintVMStartupReturnValue; jclass jclassStartup; jmethodID midStartup; //jobject obj;// jclass jobjectClass; // 确定各种文件所在的路径 // -应用的主目录 //char home[2000]; //if (!GetApplicationHome(home, sizeof(home))) { // vShowError("不能确定应用的主目录。"); // return 0; // } string sAppHome("D:\\java"); string sOption_AppHome = "-Dapplication.home=" + sAppHome; string sJREPath = sAppHome + "\\jre"; // -VM路径 string sRuntimePath = sJREPath + "\\bin\\server\\"; //jvm.dll的路径 string sJVMpath = sRuntimePath + "jvm.dll"; // -启动路径 string sBootPath = sJREPath + "\\lib"; string sOption_BootPath = "-Dsun.boot.class.path=" + sBootPath; // -CLASSPATH string sClassPath = "c:\\test\\";//AppHome + "\\classes"; Java class的类路径 string sOption_ClassPath = "-Djava.class.path=" + sClassPath; // 设置VM参数 // vAddOption(string("-verbose")); vAddOption(sOption_ClassPath); vAddOption(sOption_AppHome); // VM初始化参数 JavaVMInitArgs vm_args; vm_args.version = JNI_VERSION_1_4;//0x00010002; vm_args.options = vm_options; vm_args.nOptions = mctOptions; vm_args.ignoreUnrecognized = JNI_TRUE; // 装入JVM库 HINSTANCE hJVM = LoadLibrary(sJVMpath.c_str()); if( hJVM == NULL ){ vShowLastError("不能从下面的路径装入JVM:" + sJVMpath); return 0; } // 启动1.2/3/4 VM CreateJavaVM lpfnCreateJavaVM = (CreateJavaVM) GetProcAddress(hJVM, "JNI_CreateJavaVM"); jintVMStartupReturnValue = (*lpfnCreateJavaVM) (&jvm, &env, &vm_args); // 是否成功? if (jintVMStartupReturnValue ==JNI_ERR) { string sErrorMessage = "创建VM失败。"; vShowError(sErrorMessage); vDestroyVM(env, jvm); return 0; } // 要启动的类 string sStartupClass = "javadll"; // 注意句点符号已经被转换成斜杠 jclassStartup = env->FindClass(sStartupClass.c_str()); // obj=env->AllocObject(jclassStartup);// jobjectClass = env->GetObjectClass(obj); if (jclassStartup == NULL) { string sErrorMessage ="找不到启动类[" +sStartupClass + "]"; vShowError(sErrorMessage); vDestroyVM(env, jvm); return 0; } // 要启动的方法 string sStartupMethod_Identifier = "main"; //string sStartupMethod_Identifier = "write"; string sStartupMethod_TypeDescriptor ="([Ljava/lang/String;)V"; //string sStartupMethod_TypeDescriptor ="(Ljava/lang/String;)V"; midStartup = env->GetStaticMethodID(jclassStartup, sStartupMethod_Identifier.c_str(), sStartupMethod_TypeDescriptor.c_str()); //midStartup = env->GetMethodID(jclassStartup, sStartupMethod_Identifier.c_str(), sStartupMethod_TypeDescriptor.c_str()); if (midStartup == NULL) { string sErrorMessage = "找不到启动方法["+ sStartupClass + "."+ sStartupMethod_Identifier + "],类型描述符是[" + sStartupMethod_TypeDescriptor + "]"; vShowError(sErrorMessage); vDestroyVM(env, jvm); return 0; } // 构造启动方法的参数 jstring jstringExampleArg; jclass jclassString; jobjectArray jobjectArray_args; jstringExampleArg = env->NewStringUTF("2"); if (jstringExampleArg == NULL){ vDestroyVM(env, jvm); return 0; } jclassString = env->FindClass("java/lang/String"); jobjectArray_args = env->NewObjectArray(2, jclassString, jstringExampleArg); if (jobjectArray_args == NULL){ vDestroyVM(env, jvm); return 0; } // 调用启动方法启动Java程序 env->CallStaticVoidMethod(jclassStartup, midStartup, jobjectArray_args); // env->CallVoidMethod(obj, midStartup, jstringExampleArg); // 在退出之前尝试分离主线程 if (jvm->DetachCurrentThread() != 0) { vShowError("分离主线程失败。\n"); } // 只要还有非守护线程,下面的调用将一直被挂起 jvm->DestroyJavaVM(); MessageBox(NULL, "图片5.jpg插入成功", "welcome", MB_OK); return 0; } void vDestroyVM(JNIEnv *env, JavaVM *jvm){ if (env->ExceptionOccurred()) { env->ExceptionDescribe(); } jvm->DestroyJavaVM(); // MessageBox(NULL, "jvmdestroy呵呵", "welcome", MB_OK); } void vShowError(string sError) { MessageBox(NULL, sError.c_str(), "错误", MB_OK); } /* 在对话框中显示错误信息,括号内包含 的GetLastError错误信息 */ void vShowLastError(string sLocalError) { LPVOID lpSystemMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpSystemMsgBuf, 0, NULL ); string sSystemError = string((LPTSTR)lpSystemMsgBuf); vShowError(sLocalError + " [" + sSystemError + "]"); } void vAddOption(string& sValue) { mctOptions++; if (mctOptions >= mctOptionCapacity) { if (mctOptionCapacity == 0) { mctOptionCapacity = 3; vm_options = (JavaVMOption*)malloc(mctOptionCapacity * sizeof(JavaVMOption)); } else { JavaVMOption *tmp; mctOptionCapacity *= 2; tmp = (JavaVMOption*)malloc(mctOptionCapacity * sizeof(JavaVMOption)); memcpy(tmp, vm_options, (mctOptions-1) * sizeof(JavaVMOption)); free(vm_options); vm_options = tmp; } } vm_options[mctOptions-1].optionString = (char*)sValue.c_str(); } 在window下用vc++在Linux下用g++/gcc核心技术的例子可以使用啊! vc++的编译(要安装vc++哦)Cl -Ic:\jdk\include -Ic:\jdk\include\win32 *.c c:\jdk\lib\jvm.lib在Window下:确保PATH=c:\jdk\jre\bin\hotspot存在linux的编译gcc -I/usr/local/jdk/include -I/usr/local.jdk/include/linux -o *** -L/usr/local/jdk/jre/lib/i386/client -ljvm ***.c在Linux/Unix下:确保共享库存在LD_LIBRARY_PATH= /usr/local/jdk/jre/lib/i386/client: /usr/local/jdk/jre/lib/i386 role0523(java初学者) ???你用的什么编译器阿?vc?用了windows api 还怎么能在linux下编译通过呢 我对jni一点不懂!不过这是个很好的主题!严重关注!跟踪学习! 关于java继承的问题 Swing 用到 JFileChooser 问题 界面设计问题 怎样获取光标位置。 这问题比较简单,分稍微少点吧。在线等的。 抽象类是不能实例化的,为什么还可以有构造函数,这是基于什么得考虑?请帮忙 实在想不通了,问问各位大侠。关于InetAddress类的 代理服务器的原理是什么?如何用java实现? 数据库关系模型设计问题 怎样用java快速实现zip文件的压缩解压缩?(给分20!) 请教一个语句~~ 怎么将JTextField设置成只读
写JNI必需要熟悉c/c++的,想写JNI,现学c/c++吧。
我用java调用c成功了,可是c调用java怎么也不行。我学过c/c++,可是JNI对java调c支持的较好一些啊,能不能留下你们联系方式
小弟在此感谢了
//#include "stdafx.h"
#include <windows.h>
#include <jni.h>
#include <string>
using std::string; BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}void vShowError(string sErrorMessage);
void vShowLastError(string sErrorMessage);
void vDestroyVM(JNIEnv *env, JavaVM *jvm);
void vAddOption(string& sName); JavaVMOption* vm_options;
int mctOptions = 0;
int mctOptionCapacity = 0;
//boolean GetApplicationHome(char *buf, jint sz);
typedef jint (CALLBACK *CreateJavaVM)(JavaVM **pvm, JNIEnv **penv, void *args);
//int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){
extern "C"_declspec(dllexport)int write(char *filename){
MessageBox(NULL, "欢迎使用", "welcome", MB_OK);
JNIEnv *env;
JavaVM *jvm;
jint jintVMStartupReturnValue;
jclass jclassStartup;
jmethodID midStartup;
//jobject obj;
// jclass jobjectClass;
// 确定各种文件所在的路径
// -应用的主目录
//char home[2000];
//if (!GetApplicationHome(home, sizeof(home))) {
// vShowError("不能确定应用的主目录。");
// return 0;
// }
string sAppHome("D:\\java");
string sOption_AppHome = "-Dapplication.home=" + sAppHome;
string sJREPath = sAppHome + "\\jre";
// -VM路径
string sRuntimePath = sJREPath + "\\bin\\server\\"; //jvm.dll的路径
string sJVMpath = sRuntimePath + "jvm.dll";
// -启动路径
string sBootPath = sJREPath + "\\lib";
string sOption_BootPath = "-Dsun.boot.class.path=" + sBootPath;
// -CLASSPATH
string sClassPath = "c:\\test\\";//AppHome + "\\classes"; Java class的类路径
string sOption_ClassPath = "-Djava.class.path=" + sClassPath;
// 设置VM参数
// vAddOption(string("-verbose"));
vAddOption(sOption_ClassPath);
vAddOption(sOption_AppHome);
// VM初始化参数
JavaVMInitArgs vm_args;
vm_args.version = JNI_VERSION_1_4;//0x00010002;
vm_args.options = vm_options;
vm_args.nOptions = mctOptions;
vm_args.ignoreUnrecognized = JNI_TRUE;
// 装入JVM库
HINSTANCE hJVM = LoadLibrary(sJVMpath.c_str());
if( hJVM == NULL ){
vShowLastError("不能从下面的路径装入JVM:" + sJVMpath);
return 0;
}
// 启动1.2/3/4 VM
CreateJavaVM lpfnCreateJavaVM = (CreateJavaVM) GetProcAddress(hJVM, "JNI_CreateJavaVM");
jintVMStartupReturnValue = (*lpfnCreateJavaVM) (&jvm, &env, &vm_args); // 是否成功?
if (jintVMStartupReturnValue ==JNI_ERR) {
string sErrorMessage = "创建VM失败。";
vShowError(sErrorMessage);
vDestroyVM(env, jvm);
return 0;
}
// 要启动的类
string sStartupClass = "javadll";
// 注意句点符号已经被转换成斜杠 jclassStartup = env->FindClass(sStartupClass.c_str());
// obj=env->AllocObject(jclassStartup);
// jobjectClass = env->GetObjectClass(obj);
if (jclassStartup == NULL) {
string sErrorMessage ="找不到启动类[" +sStartupClass + "]";
vShowError(sErrorMessage);
vDestroyVM(env, jvm);
return 0;
}
// 要启动的方法
string sStartupMethod_Identifier = "main";
//string sStartupMethod_Identifier = "write";
string sStartupMethod_TypeDescriptor ="([Ljava/lang/String;)V";
//string sStartupMethod_TypeDescriptor ="(Ljava/lang/String;)V";
midStartup = env->GetStaticMethodID(jclassStartup, sStartupMethod_Identifier.c_str(), sStartupMethod_TypeDescriptor.c_str());
//midStartup = env->GetMethodID(jclassStartup, sStartupMethod_Identifier.c_str(), sStartupMethod_TypeDescriptor.c_str());
if (midStartup == NULL) {
string sErrorMessage = "找不到启动方法["+ sStartupClass + "."+ sStartupMethod_Identifier
+ "],类型描述符是[" + sStartupMethod_TypeDescriptor + "]";
vShowError(sErrorMessage);
vDestroyVM(env, jvm);
return 0;
}
// 构造启动方法的参数
jstring jstringExampleArg;
jclass jclassString;
jobjectArray jobjectArray_args;
jstringExampleArg = env->NewStringUTF("2");
if (jstringExampleArg == NULL){
vDestroyVM(env, jvm);
return 0;
}
jclassString = env->FindClass("java/lang/String");
jobjectArray_args = env->NewObjectArray(2, jclassString, jstringExampleArg);
if (jobjectArray_args == NULL){
vDestroyVM(env, jvm);
return 0;
}
// 调用启动方法启动Java程序
env->CallStaticVoidMethod(jclassStartup, midStartup, jobjectArray_args);
// env->CallVoidMethod(obj, midStartup, jstringExampleArg);
// 在退出之前尝试分离主线程
if (jvm->DetachCurrentThread() != 0) {
vShowError("分离主线程失败。\n");
}
// 只要还有非守护线程,下面的调用将一直被挂起
jvm->DestroyJavaVM();
MessageBox(NULL, "图片5.jpg插入成功", "welcome", MB_OK);
return 0;
}
void vDestroyVM(JNIEnv *env, JavaVM *jvm){
if (env->ExceptionOccurred()) {
env->ExceptionDescribe();
}
jvm->DestroyJavaVM();
// MessageBox(NULL, "jvmdestroy呵呵", "welcome", MB_OK);
} void vShowError(string sError) {
MessageBox(NULL, sError.c_str(), "错误", MB_OK);
} /* 在对话框中显示错误信息,括号内包含
的GetLastError错误信息 */
void vShowLastError(string sLocalError) {
LPVOID lpSystemMsgBuf;
FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpSystemMsgBuf, 0, NULL );
string sSystemError = string((LPTSTR)lpSystemMsgBuf);
vShowError(sLocalError + " [" + sSystemError + "]");
} void vAddOption(string& sValue) {
mctOptions++;
if (mctOptions >= mctOptionCapacity) {
if (mctOptionCapacity == 0) {
mctOptionCapacity = 3;
vm_options = (JavaVMOption*)malloc(mctOptionCapacity * sizeof(JavaVMOption));
} else {
JavaVMOption *tmp;
mctOptionCapacity *= 2;
tmp = (JavaVMOption*)malloc(mctOptionCapacity * sizeof(JavaVMOption));
memcpy(tmp, vm_options, (mctOptions-1) * sizeof(JavaVMOption));
free(vm_options);
vm_options = tmp;
}
}
vm_options[mctOptions-1].optionString = (char*)sValue.c_str();
}
在Linux下用g++/gcc
核心技术的例子可以使用啊!
Cl -Ic:\jdk\include -Ic:\jdk\include\win32 *.c c:\jdk\lib\jvm.lib在Window下:确保PATH=c:\jdk\jre\bin\hotspot存在
linux的编译
gcc -I/usr/local/jdk/include -I/usr/local.jdk/include/linux -o ***
-L/usr/local/jdk/jre/lib/i386/client -ljvm ***.c
在Linux/Unix下:确保共享库存在LD_LIBRARY_PATH=
/usr/local/jdk/jre/lib/i386/client: /usr/local/jdk/jre/lib/i386
不过这是个很好的主题!
严重关注!
跟踪学习!