C调java_语言混编之c调用java

经过验证可以实现,先将实现代码贴出,以备以后使用。

本文默认你的java开发环境已经安装成功,并且对于java语言和c++语言有过了解。

编写测试用类:Demo.java

代码如下:

public class Demo

{

public static int COUNT = 8;

private String msg;

private int[] counts;

public Demo ()

{

this ("default constructor");

}

public Demo (String msg)

{

this.msg = msg;

this.counts = null;

}

public String getMessage ()

{

return msg;

}

public static String getHelloWorld ()

{

return "hello world!";

}

public String append (String str, int i)

{

return str + i;

}

public int[] getCounts ()

{

return counts;

}

public void setCounts (int[] counts)

{

this.counts = counts;

}

public void throwExcp () throws IllegalAccessException

{

throw new IllegalAccessException ("exception occurs");

}

}

由于在java中能够使用函数重载,所以在c语言中调用java是需要确定究竟是调用的是那个函数。在jdk中提供了javap程序。

Javap将一个类和它的方法的一些转储信息输出到标准输出。该工具不把代码反编译为java源代码,但是它会把字节代码反汇编成为由Java虚拟机规范定义的字节代码指令。其用法如下:

-l     输出本地变量表

-public    输出公用类名和方法名

-protected   输出类的受保护方法

-private   输出类的似有方法

-verbose  输出类的栈的信息和本地方法的个数

回到原来主题:

javap -s -p Demo

无法上传图片^_^想象一下吧。在输出中找到如下的语句:

public java.lang.String append(java.lang.String, int);

Signature: (Ljava/lang/String;I)Ljava/lang/String;

在vs2008中新建一个工程(win32 console application),配置工程属性:将jdk中include目录下的头文件加入到工程中,并将该文夹下的win32子目录下的header file同样加入到工程中。

新建main.cpp

代码如下:

#include

#include "jni.h"

#include

#include

using namespace std;

jstring NewJString (JNIEnv* env, LPCTSTR str);

string  JStringToCString (JNIEnv *env, jstring str);

int main ()

{

typedef jint (WINAPI* PFunCreateJavaVM) (JavaVM**, void**, void*);

int res;

JavaVMInitArgs vm_args;

JavaVMOption options[3];

JavaVM* jvm;

JNIEnv* env;

options[0].optionString = options[0].optionString = "-Djava.compiler=NONE";

//classpath should be set to find the .class file in the following

//here we put the class file in the directory c:\ Demo.class

options[1].optionString = "-Djava.class.path=.;C:\\";

options[2].optionString = "-verbose:NONE";

vm_args.version = JNI_VERSION_1_4;

vm_args.nOptions = 3;

vm_args.options = options;

vm_args.ignoreUnrecognized = JNI_TRUE;

//load the dll

HINSTANCE hInstance = ::LoadLibrary("C:\\Program Files\\Java\\jdk1.6.0_10\\jre\\bin\\client\\jvm.dll");

if (hInstance == NULL)

return 1;

PFunCreateJavaVM funCreateJavaVM = (PFunCreateJavaVM)::GetProcAddress(hInstance, "JNI_CreateJavaVM");

res = (*funCreateJavaVM)(&jvm, (void**)&env, &vm_args);

if (res < 0)

{

return -1;

}

jclass cls = env->FindClass("Demo");

jobject obj = env->AllocObject(cls);

jmethodID mid = env->GetMethodID(cls, "append","(Ljava/lang/String;I)Ljava/lang/String;");

const char szTest[] = "HELLO WORLD";

jstring arg = NewJString(env, szTest);

jstring msg = (jstring) env->CallObjectMethod(obj, mid, arg, 12);

cout << JStringToCString(env, msg);

jvm->DestroyJavaVM();

::FreeLibrary(hInstance);

return 0;

}

string  JStringToCString (JNIEnv *env, jstring str)// (jstring str, LPTSTR desc, int desc_len)

{

if(str==NULL)

{

return "";

}

int len = env->GetStringLength(str);

wchar_t *w_buffer = new wchar_t[len+1];

//char* w_buffer = new char [len + 1];

char *c_buffer = new char[2*len+1];

ZeroMemory(w_buffer,(len+1)*sizeof(wchar_t));

const jchar * jcharString = env->GetStringChars(str, 0);

wcscpy(w_buffer,(wchar_t*)jcharString);

env->ReleaseStringChars(str,jcharString);

ZeroMemory(c_buffer,(2*len+1)*sizeof(char));

len = WideCharToMultiByte(CP_ACP, 0, w_buffer, len, c_buffer, 2 * len, NULL, NULL);

string cstr = c_buffer;

delete[] w_buffer;

delete[] c_buffer;

return cstr;

}

jstring NewJString(JNIEnv *env, LPCTSTR str)

{

if(!env || !str)

{

return 0;

}

int slen = strlen(str);

jchar* buffer = new jchar[slen];

int len = MultiByteToWideChar(CP_ACP,0,str,strlen(str), (LPWSTR)buffer,slen);

if(len>0 && len < slen)

{

buffer[len]=0;

}

jstring js = env->NewString(buffer,len);

delete [] buffer;

return js;

}

注意上面的路径的使用需要根据本地的文件路径来设置。编译运行即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值