java中使用C++指针实现java调用C#
来源:互联网 发布:淘宝怎么下载到桌面 编辑:程序博客网 时间:2024/06/15 09:46
运行结果图:
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 __cplusplusextern "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
- java中使用C++指针实现java调用C#
- C#实现调用Java类中方法
- C#实现调用Java类中方法
- JNI编程中C调用Java实现。
- 实现java调用c
- 使用jni实现在C语言中调用Java的方法
- 在java中实现调用简单的c程序
- 在java中实现调用简单的c程序
- Android中java调用C的实现jniNDK
- JAVA中native方法调用C语言实现学习
- Java中调用C库函数
- 使用Java调用C/C++
- 使用Java调用C/C++
- 如何使用java调用c
- 在C#中调用 java的函数(C#与java结合使用)
- Android中使用反射实现类似于C语言指针的调用
- 使用JNI在C中调用java代码
- 使用JNI在java中调用C代码
- java类的实例化探究
- Alberta教育:2011预算+北京比较
- dreamweaver随记-----dreamweaver中的“内连接”“外连接”
- ANE + NDK on Android emulator
- 如何获取本机的Mac 以及IP地址(不用gethostbyname)
- java中使用C++指针实现java调用C#
- Multi-Core CPU articles
- clearcase下载地址
- prototype修改添加位置的影响
- war3骚招之剑牛拆家流
- 81. Beauty lies in the lover's eyes. 情人眼里出西施
- 多进程与多线程(二)
- IBM完成对安全软件厂商Q1 Labs并购
- 如使真正快速实现社保系统全国性通刷通兑呢?