2,编译 JNI为 C/C++ 接口
编译命令:
javah –jni CTeamMgr // 这一步需要 CTeamMgr.class文件
// 生成 CTeamMgr_jni_impl.h
其中有这样的定义:
JNIEXPORT jint JNICALL Java_CTeamMgr_GetTeamMeb
(JNIEnv *, jobject, jstring, jobject, jint, jobject);
3,实现上述接口,生成动态库
创建 CTeamMgr_jni_impl.cpp,实现 CTeamMgr_jni_impl.h中的接口:
JNIEXPORT jint JNICALL Java_CTeamMgr_GetTeamMeb(
JNIEnv* jEnv, // interface pointer
jobject jObj, // "this" pointer
jstring jTeamName, // argument #1
jobject jteamMebs, // argument #2
jint jiIn, // argument #3
jobject jiOut // argument #4
)
{
jint iRlt = 0;
int iOut = 0;
std::string strTeamName;
TeamMebs teamMebs;
TeamMebs::iterator p;
// trans in data
strTeamName = jEnv->GetStringUTFChars( jTeamName,false );
iOut = jIntegerValue( jEnv, jiOut );
// 下面的代码省略
}
编译生成的动态库为:teamMgr_jni_impl.dll
4,如何在C++实现中创建一个Java对象(调用Java类的构造函数)
jclass jc = jEnv->FindClass( "TeamMeb" );
jmethodID jConstructMid = jEnv->GetMethodID( jc, "<init>", "()V"); //第三个参数为方法的sig
jobject jObj = jEnv->NewObject( jc, jConstructMid);
如果构造函数有参数,会有什么不一样呢?
下面的例子中,构造函数有一个int类性的参数
:
jclass jc = jEnv->FindClass( "TeamMeb" );
jmethodID jConstructMid = jEnv->GetMethodID( jc, "<init>", "(I)V");
jobject jObj = jEnv->NewObject( jc, jConstructMid, 100 );
如果构造函数的参数为String类型,则函数的sig为:
"(Ljava/lang/String;)V"
5,Java中简单类型(int)不能作为输出参数
如果C++方法中有一个“int&”类型的参数,在Java中就需要把这个参数定义为“Integer”类型,在实现代码中可以按照下面的方法改变输出参数的值:
jclass jci = jEnv->GetObjectClass( intObj );
jmethodID jIntConstruct = jEnv->GetMethodID( jci, "<init>", "(I)V");
jEnv->CallVoidMethod( intObj, jIntConstruct, 100 );