java中使用C++指针实现java调用C#
2011-10-27 07:05
981 查看
运行结果图:
Access.java代码:
头文件产生命令行:
javah jxdo.iclr.Access
得到如下头文件:
CPP对于头文件的实现:
其它省去,可以按这个方式继续实现头文件中的代码...
代码说明:
void* umgdClr存放了一个指针
Java_jxdo_iclr_Access_nGetType 返回一个拖管代码Type类型的指针,返回给JAVA端,便于创建拖管对象.
Java_jxdo_iclr_Access_nCreateInstance__I中的iTypePtr参数就是上面返回的指针.
都说JAVA中没有指针,其实这个int值,就是一个指针值.
CPP中使用混编,可以得到拖管对象指针:
从JAVA中将指针值重新传到CPP中的处理,需要恢复出这个指针
CPP的拖管代码(ikvmClrBridge类的头文件):
拖管代码ikvmClrBridge类的头文件具体实现
其它省去,可以按这个方式继续实现拖管头文件中的代码...
读者可以扩充,实现参数的传入,方法的返回值,属性等代码的调用.
测试的C#代码:
JAVA端调用代码:
如需转载,请注明出处.
javasuki@hotmail.com
Access.java代码:
package jxdo.iclr; public class Access { private native void nLoad(String asmFileName); private native int nGetType(String typeName); private native int nCreateInstance(int iTypePointer); private native int nCreateInstance(String typeName); private native void nInvokeStatic(int iTypePointer, String methodName); private native void nInvoke(int iObjectPointer, String methodName); static { System.loadLibrary("NXDO.IKMX"); } public static Access load(String asmFileName) { Access ace = new Access(); ace.nLoad(asmFileName); return ace; } public int getType(String typeName) { return this.nGetType(typeName); } public int createInstance(int iTypePointer) { return this.nCreateInstance(iTypePointer); } public int createInstance(String typeName) { return this.nCreateInstance(typeName); } public void invokeStatic(int iTypePointer, String methodName) { this.nInvokeStatic(iTypePointer,methodName); } public void invoke(int iObjectPointer, String methodName) { this.nInvoke(iObjectPointer,methodName); } }
头文件产生命令行:
javah jxdo.iclr.Access
得到如下头文件:
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class jxdo_iclr_Access */ #ifndef _Included_jxdo_iclr_Access #define _Included_jxdo_iclr_Access #ifdef __cplusplus extern "C" { #endif /* * Class: jxdo_iclr_Access * Method: nLoad * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_jxdo_iclr_Access_nLoad (JNIEnv *, jobject, jstring); /* * Class: jxdo_iclr_Access * Method: nGetType * Signature: (Ljava/lang/String;)I */ JNIEXPORT jint JNICALL Java_jxdo_iclr_Access_nGetType (JNIEnv *, jobject, jstring); /* * Class: jxdo_iclr_Access * Method: nCreateInstance * Signature: (I)I */ JNIEXPORT jint JNICALL Java_jxdo_iclr_Access_nCreateInstance__I (JNIEnv *, jobject, jint); /* * Class: jxdo_iclr_Access * Method: nCreateInstance * Signature: (Ljava/lang/String;)I */ JNIEXPORT jint JNICALL Java_jxdo_iclr_Access_nCreateInstance__Ljava_lang_String_2 (JNIEnv *, jobject, jstring); /* * Class: jxdo_iclr_Access * Method: nInvokeStatic * Signature: (ILjava/lang/String;)V */ JNIEXPORT void JNICALL Java_jxdo_iclr_Access_nInvokeStatic (JNIEnv *, jobject, jint, jstring); /* * Class: jxdo_iclr_Access * Method: nInvoke * Signature: (ILjava/lang/String;)V */ JNIEXPORT void JNICALL Java_jxdo_iclr_Access_nInvoke (JNIEnv *, jobject, jint, jstring); #ifdef __cplusplus } #endif #endif
CPP对于头文件的实现:
void* umgdClr; JNIEXPORT void JNICALL Java_jxdo_iclr_Access_nLoad(JNIEnv* env, jobject obj, jstring asmFileName) { String^ dllName = ikvmClrBridge::ToClrString(env,asmFileName); ikvmClrBridge^ mgd = gcnew ikvmClrBridge(); try { mgd->Load(dllName); } catch (Exception^ ex) { const char* exStr = ikvmClrBridge::ToCppChar(ex->Message); jclass errclass = env->FindClass("java/lang/Exception"); env->ThrowNew(errclass, exStr);//向java中抛出异常 ikvmClrBridge::FreeCppString(exStr); return; } umgdClr = ikvmClrBridge::getPtrVoid(mgd); } JNIEXPORT jint JNICALL Java_jxdo_iclr_Access_nGetType(JNIEnv* env, jobject obj, jstring clrTypeName) { ikvmClrBridge^ mgd = (ikvmClrBridge^)(ikvmClrBridge::getObject(umgdClr)); String^ typeName = ikvmClrBridge::ToClrString(env,clrTypeName); Type^ type = nullptr; try { type = mgd->GetType(typeName); } catch (Exception^ ex) { const char* exStr = ikvmClrBridge::ToCppChar(ex->Message); jclass errclass = env->FindClass("java/lang/Exception"); env->ThrowNew(errclass, exStr); ikvmClrBridge::FreeCppString(exStr); return 0; } return ikvmClrBridge::getPtrInt(type); } JNIEXPORT jint JNICALL Java_jxdo_iclr_Access_nCreateInstance__I(JNIEnv* env, jobject obj, jint iTypePtr) { ikvmClrBridge^ mgd = (ikvmClrBridge^)(ikvmClrBridge::getObject(umgdClr)); int clrTypePtr = iTypePtr; Object^ clrObj = nullptr; try { clrObj = mgd->CreateInstance((Type^)(ikvmClrBridge::getObject(clrTypePtr))); } catch (Exception^ ex) { const char* exStr = ikvmClrBridge::ToCppChar(ex->Message); jclass errclass = env->FindClass("java/lang/Exception"); env->ThrowNew(errclass, exStr); ikvmClrBridge::FreeCppString(exStr); return 0; } int iObjPtr = GCHandle::ToIntPtr(GCHandle::Alloc(clrObj)).ToInt32(); return iObjPtr; }
其它省去,可以按这个方式继续实现头文件中的代码...
代码说明:
void* umgdClr存放了一个指针
Java_jxdo_iclr_Access_nGetType 返回一个拖管代码Type类型的指针,返回给JAVA端,便于创建拖管对象.
Java_jxdo_iclr_Access_nCreateInstance__I中的iTypePtr参数就是上面返回的指针.
都说JAVA中没有指针,其实这个int值,就是一个指针值.
CPP中使用混编,可以得到拖管对象指针:
{ int iPtr = GCHandle::ToIntPtr(GCHandle::Alloc(obj)).ToInt32(); return iPtr; }iPtr就是对象指针,可以直接设置给jint,返回到JAVA代码中.
从JAVA中将指针值重新传到CPP中的处理,需要恢复出这个指针
Object^ ikvmClrBridge::getObject(int iPtr) { GCHandle gch = GCHandle::FromIntPtr(IntPtr(iPtr)); return gch.Target; }
CPP的拖管代码(ikvmClrBridge类的头文件):
ref class ikvmClrBridge { private: Assembly^ asmLoad; Dictionary<String^, Type^>^ dicTypes; MethodInfo^ GetMethod(Type^ type,String^ methodName); internal: static int getPtrInt(Object^ obj); static void* getPtrVoid(Object^ obj); static Object^ getObject(int iPtr); static Object^ getObject(void* voidPtr); static String^ ToClrString(JNIEnv* env, jstring jstr); static const char* ToCppChar(String^ str); static void FreeCppString(const char* str); public: ikvmClrBridge(void); void Load(String^ dllName); Type^ GetType(String^ typeName); Object^ CreateInstance(Type^ type); Object^ CreateInstance(String^ typeName); void Invoke(Object^ obj, String^ methodName); void Invoke(Type^ type,String^ methodName); };
拖管代码ikvmClrBridge类的头文件具体实现
void ikvmClrBridge::Load(String^ dllName) { String^ asmDllName = dllName; if (!File::Exists(asmDllName)) { String^ path = AppDomain::CurrentDomain->BaseDirectory; asmDllName = Path::Combine(path, asmDllName); } if (!File::Exists(asmDllName)) throw gcnew FileNotFoundException("clr not found file:" + dllName); this->asmLoad = Assembly::LoadFile(asmDllName); } Type^ ikvmClrBridge::GetType(String^ typeName) { bool b = this->dicTypes->ContainsKey(typeName); if (b) return this->dicTypes[typeName]; Type^ type = this->asmLoad->GetType(typeName); if (type == nullptr) throw gcnew TargetException("clr not found type:"+typeName); this->dicTypes->Add(typeName, type); return type; } Object^ ikvmClrBridge::CreateInstance(Type^ type) { return Activator::CreateInstance(type); }
其它省去,可以按这个方式继续实现拖管头文件中的代码...
读者可以扩充,实现参数的传入,方法的返回值,属性等代码的调用.
测试的C#代码:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ClassLibrary1 { public class Class1 { public void Who() { Console.WriteLine("i'm C# Class1!"); } public static void WhoStatic() { Console.WriteLine("i'm C#,static!"); } } public class Class2 { public void Who() { Console.WriteLine("i'm C# Class2!"); } } }
JAVA端调用代码:
package jxdo.iclr; public class test { public static void main(String[] args) { Access ace = Access.load("d:\\ClassLibrary1.dll"); int iType = ace.getType("ClassLibrary1.Class1"); ace.invokeStatic(iType, "WhoStatic"); int iObj = ace.createInstance(iType); ace.invoke(iObj, "Who"); int iObj2 = ace.createInstance("ClassLibrary1.Class2"); ace.invoke(iObj2, "Who"); } }
如需转载,请注明出处.
javasuki@hotmail.com
相关文章推荐
- C#调用C++生成的Dll库,Dll使用callback向C#传递指针
- 用Swig将c/c++程序转为java代码(使用swig实现java调用c、c++的方法)
- C#调用exe解决PDF转图片问题(使用PDFBox方案,java语言编译jar包实现)
- linux下使用jni实现c++调用java程序(2)找不到java类的问题
- linux下使用jni实现c++调用java程序(1)准备工作
- 1ActiveMQ使用 2ActiveMQC#Client实现 3ActiveMQC++Client实现通讯 4 ActiveMQJavaClient实现
- linux下使用jni实现c++调用java程序(4)DestroyJavaVM出现错误
- linux下使用jni实现c++调用java程序(3)多线程jni使用
- 使用IDispatch::Invoke函数在C++中调用C#实现的托管类库方法
- 使用IDispatch::Invoke函数在C++中调用C#实现的托管类库方法
- 使用JNI实现java调用c++
- C++ 实现类似java c#List的方法 boost::any的使用
- linux下使用jni实现c++调用java程序(5)参考资料总结
- 在C++中,要实现动态联编,必须使用(基类指针)调用虚函
- 使用IDispatch::Invoke函数在C++中调用C#实现的托管类库方法
- Java使用JNI调用C++实现Hello jni
- c# 调用c++ 使用指针传递的时候
- 转:使用IDispatch::Invoke函数在C++中调用C#实现的托管类库方法
- 使用 SWIG 实现 Java 调用 C++ DLL
- cocos2dx 使用jni实现java调用c++