Java无法直接调用C# dll,需要通过经过桥接的方式,进行中继转发一下请求。查阅大量资料,做了大量实验,不停的调试、排错之后,期间试过jni4net,不过这个插件需要修改原有的C# DLL内容,还会生成一些额外的Java代码,jni4net侵入性太多,将它排除。最后通过管理性的C++桥接方式,成功完成了Java调用C# DLL。
国内很多文章都是只有文章,没有在文中附上完整的代码工程,导致读者做实验时非常麻烦。而老外经常会带上完整的代码工程,这让读者做实验时参考起来非常方便。本文附上完整的Java、C++、CSharp代码工程,供大家参考。
实验环境:
64位 Win 7
jdk1.7.0_51
Eclipse 4.3.1
Visual Studio 2010
具体的实现步骤如下:
1,新建一个Java项目TestJNI,定义一个Java客户端类 TestJNI.java
package msg; public class TestJNI { public native boolean MasSentMessage(String a, String b); public native int add(int a, int b); public native String submit(String a, String b); public native boolean testBoolean(String a, String b); static { System.loadLibrary("CPP"); } public static void main(String[] args) { TestJNI t = new TestJNI(); // System.out.println(t.MasSentMessage("user", "pass")); // System.out.println(t.add(2, 20)); System.err.println(t.submit("user", "pass")); // System.err.println(t.testBoolean("1", "pass")); } }
2,调用JDK里的javah命令通过TestJNI.java类生成msg_TestJNI.h文件,javah设置如下,
3,在Visual Studio 2010新建一个C#项目CSharp(项目类型为Visual C# -->Windows?类库)
编辑C#文件如下:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace OJMain { public class OJEntrance { private int result; public int Result { get { return result + 10; } set { this.result = value; } } public string submit(string str1, string str2) { Console.WriteLine("成功调用了dll"); return "CSharp:" + str1 + ":" + str2; } public bool testBoolean(string str1, string str2) { if (str1.Equals("true")) { return true; } else { return false; } } } }
4,利用Visual Studio 2010 生成dll。
如果调用C#项目的Java客户端在64位的机器上,需要重新生成dll,在Visual Studio 2010的生成参数设置如下,将目标平台设为“Any CPU”
5,在Visual Studio 2010中新建一个win32 dll模式的C++项目CPP,为了在Java和C#之间的调用建立通道并进行转接。
5.1设置两个项目属性
一,项目属性-->配置属性--> 常规:“公共语言运行时支持”设为“公共语言运行时支持(/clr)”
二,项目属性-->配置属性-->C/C++-->代码生成:“运行库”设为“多线程DLL(/MD)”
5.2 C++源文件的目录里放置如下内容:
- JDK目录里的两个h文件(jni.h,jni_md.h);
- Java项目中生成的msg_TestJNI.h;
- C#项目CSharp中生成的CSharp.dll ;
5.3编写jstring 和 string的相互转换功能,完整代码参见附件 CPP.rar(CPP.cpp)。
// char* To jstring jstring stringTojstring(JNIEnv* env, const char* pat) { jclass strClass = env->FindClass("Ljava/lang/String;"); jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V"); jbyteArray bytes = env->NewByteArray(strlen(pat)); env->SetByteArrayRegion(bytes, 0, strlen(pat), (jbyte*)pat); jstring encoding = env->NewStringUTF("utf-8"); return (jstring)env->NewObject(strClass, ctorID, bytes, encoding); } // jstring To char* char* jstringTostring(JNIEnv* env, jstring jstr) { char* rtn = NULL; jclass clsstring = env->FindClass("java/lang/String"); jstring strencode = env->NewStringUTF("utf-8"); jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B"); jbyteArray barr = (jbyteArray)env->CallObjectMethod(jstr, mid, strencode); jsize alen = env->GetArrayLength(barr); jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE); if (alen > 0) { rtn = (char*)malloc(alen + 1); memcpy(rtn, ba, alen); rtn[alen] = 0; } env->ReleaseByteArrayElements(barr, ba, 0); return rtn; } // jstring To String String^ jstringToStr(JNIEnv* env, jstring jstr) { char* str = jstringTostring(env, jstr); String^ value = gcnew String(str); free(str); return value; } // String To jstring jstring strTojstring(JNIEnv* env, String^ rtn) { pin_ptr<const wchar_t> wch = PtrToStringChars(rtn); size_t convertedChars = 0; size_t sizeInBytes = ((rtn->Length + 1) * 2); char *ch = (char *)malloc(sizeInBytes); errno_t err = wcstombs_s(&convertedChars, ch, sizeInBytes, wch, sizeInBytes); jstring js = stringTojstring(env, ch); free(ch); return js; }
5.4 编写C++的管理类, 完整代码参见附件 CPP.rar(CPP.cpp)
#include "jni.h" #include "jni_md.h" #include "msg_TestJNI.h" //引入c#的库和命名空间 #using "CSharp.dll" using namespace OJMain; …… ….. JNIEXPORT jint JNICALL Java_msg_TestJNI_add (JNIEnv *env, jobject obj, jint a, jint b) { //c#中的对象 OJEntrance ^o = gcnew OJEntrance(); o->Result = a + b; return o->Result; } JNIEXPORT jstring JNICALL Java_msg_TestJNI_submit (JNIEnv *env, jobject obj, jstring str1, jstring str2) { //c#中的对象 OJEntrance ^o = gcnew OJEntrance(); return strTojstring(env, o->submit(jstringToStr(env,str1), jstringToStr(env,str2))); } JNIEXPORT jboolean JNICALL Java_msg_TestJNI_testBoolean (JNIEnv *env, jobject obj, jstring str1, jstring str2) { //c#中的对象 OJEntrance ^o = gcnew OJEntrance(); return o->testBoolean(jstringToStr(env,str1), jstringToStr(env,str2)); }
5.5利用Visual Studio 2010生成CPP.dll
6,JDK的bin目录里放置如下内容
- C# 项目CSharp中生成的CSharp.dll ;
- C++项目CPP中生成的CPP.dll;
7,在Java项目TestJNI中 运行TestJNI,调用C# dll。
相关推荐
该资源包含C#开发DLL源码,Java调用DLL源码,测试已通过
Java调用C# dll jacob包类资源.zip
java调用C#封装的dll方法 关于java调用C# 封装的DLL文件的方法 第一种:java利用JNA进行调用 思路:C#源码生成COM组件(dll和tlb文件),再利用C++进行封装,java通过JNA调用C++封装的DLL。 第二种:java利用jacob...
java调用C#封装的dll(jna,com)java调用C#封装的dll(jna,com)java调用C#封装的dll(jna,com)
最近一段时间单位在做一个Web项目,工程师用JAVA语言,需要公用人员信息,统一用户名和密码,原有的平台中是用C#语言开发的,在网上查找解决方法,通过JAVA调用C#的DLL文件实现。网上资料很多,自己整合总结了一下,...
Java调用通过jni调用C#dll,实现跨语言调用
利用Jacob库从java调用c# dll的样例程序,实现了从java调用c# dll的简单方案,供大家学习参考。
本资源包括JAVA工程,C++工程,C#dll测试工程
详细资料(图解) 博文链接:https://u012385634.iteye.com/blog/2002871
Java通过JNI调用DLL动态库,亲测试编写
java 调用DLL的方法,使用教程http://blog.csdn.net/pplcheer/article/details/52234697
java调用C#封装的dll方法[归纳].pdf
JAVA 调用 C#编写的DLL,详细说明
里面有一个world文档,里面详细介绍从c#编写的dl到java成功调用dll的整个完整过程;还有一个要用到的jar包
java操纵com组件–java调用C#写的DLL文件. 是一个完整的例子,包含源码和dll文件,已经一些必备的jar包和工具。 用的是jacob方式~
JNI实现的DEMO Java调用VC6编写的DLL,对应于Linux .SO 包含C的项目和Java的Eclipse项目
前一段时间接了个项目,需要用到第三方提供的C#编写的dll,本身项目是java语言,所以便有了下面这篇文章,本文给大家介绍了关于java中如何使用jna调用c#中dll的相关资料,文中通过示例代码介绍的非常详细,需要的...