java 调用c 乱码_java调用c/c++代码简单实现以及遇见的坑

以下内容均来自互联网,感谢你们的分享,我只是使用的时候看这方便,可以称呼我“搬运工”

如有不合适的地方请与我联系,我会及时改正

首先你可能会遇见以下错误

第一个错误是你在vs编译器没有选择使用release版的,而是用debug版的

详细见http://blog.csdn.net/niuxinlong/article/details/4176612

F:\java>java testdll

Exceptionin thread "main"java.lang.UnsatisfiedLinkError: F:\java\testdll.dll:

应用程序无法启动,因为应用程序的并行配置不正确。有关详细信息,请参阅应用程序事件

日志,或使用命令行 sxstrace.exe 工具。

at java.lang.ClassLoader$NativeLibrary.load(Native Method)

at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)

at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857)

at java.lang.Runtime.loadLibrary0(Runtime.java:870)

at java.lang.System.loadLibrary(System.java:1122)

at testdll.(testdll.java:5)

第二个是在64位运行了一个32位dll

C:\testjni\testdll\x64\Debug>java testdll

Exceptionin thread "main"java.lang.UnsatisfiedLinkError: C:\testjni\testdll\x64\Debug\testdll.dll: Can't load AMD 64-bit .dll on a IA 32-bit platform

at java.lang.ClassLoader$NativeLibrary.load(Native Method)

at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1807)

at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1732)

at java.lang.Runtime.loadLibrary0(Runtime.java:823)

at java.lang.System.loadLibrary(System.java:1028)

at testdll.(testdll.java:5)

Could not find the mainclass: testdll. Program will exit.

第三个当然是编码问题喽,编译class时使用encoding参数

C:\Users\Dmeck\Desktop\Java\winbox>javac -encoding gb2312 Testwin.java

C:\Users\Dmeck\Desktop\Java\winbox>java Testwin8

234中文乱码

—————————————————————Body———————————————————————————————————

好了下面一个xp简单实现,

环境:java1.6、MinGw、sublime、xp32、vs2008

在硬盘准备一个目录

2768ac95aaaade476515076eb674c984.png

编写一个java加载JNi的本地实现

testdll.java

public classtestdll

{static{

System.loadLibrary("testdll");

}public native static intget();public native static void set(inti);public static voidmain(String[] args)

{

testdll test= newtestdll();

test.set(10);

System.out.println(test.get());

}

}

cmd进入以上目录

运行

javac testdll.java

得到class

javah testdll

得到c的头文件

此处有两种方式:

一个把java安装目录的include目录

jni.h以及32目录下的jni_md.h复制当前工作目录

第二个是直接进行下一步

下一步:查看并修改刚刚编译的头文件testdll.h

/*DO NOT EDIT THIS FILE - it is machine generated*/#include

/*Header for class testdll*/#ifndef _Included_testdll#define _Included_testdll#ifdef __cplusplusextern "C"{#endif

/** Class: testdll

* Method: get

* Signature: ()I*/JNIEXPORT jint JNICALL Java_testdll_get

(JNIEnv*, jclass);/** Class: testdll

* Method: set

* Signature: (I)V*/JNIEXPORTvoidJNICALL Java_testdll_set

(JNIEnv*, jclass, jint);

#ifdef __cplusplus

}#endif

#endif

修改全局引用为本地目录引用

#include 改为

#include ”jni.h“

之后在当前目录编写cpp实现头文件的方法

#include "testdll.h"

int i = 0;

JNIEXPORT jint JNICALL Java_testdll_get(JNIEnv*, jclass)

{returni;

}

JNIEXPORTvoid JNICALL Java_testdll_set(JNIEnv *, jclass, jint j)

{

i=j;

}

接着运行gcc

当然本例是winxp32位默认编译是32位dll

以下是博客参考博客地址

https://www.zhihu.com/question/36666057/answer/68516501

事实上很多情况下那样调用都是不成功的,生成dll代码一般这样最完整

gcc -Wl,--add-stdcall-alias -I "C:\Program Files\Java\jdk1.6.0_31\include" -I "C:\Program Files\Java\jdk1.6.0_31\include\win32" -shared -o testdll.dll testdll.cpp

当你使用gcc的-m64编译64位dll会出现

C:\Documents and Settings\Administrator\桌面\java1>gcc -m64 -Wl,--add-stdcall-al

ias-I "C:\Program Files\Java\jdk1.6.0_31\include" -I "C:\Program Files\Java\jdk

1.6.0_31\include\win32"-shared -o testdll.dll testdll.cpp

testdll.cpp:1:0: sorry, unimplemented: 64-bit mode not compiled in#include"testdll.h"

所以这时候用编译工具最合适了vs2008很老,但相关博客比较多

本例是在windows下做的,生成的是dll文件。并且名称要与java中需要调用的一致,这里就是testdll.dll (跟testdll.java没有关系)

把testdll.dll 拷贝到testdll.class的目录下,java testdll运行它,就可以观察到结果了

C:\Documents and Settings\Administrator\桌面\java1>java testdll1000

下面介绍vs2008下编译64位

参考http://blog.csdn.net/a_little_e/article/details/45397557

——————————————————————————END——————————————————————————————————

同样最后我们只需要三个文件

testdll.class、testdll32.dll、testdll64.dll

当然testdll.class需要对应的testdll.java源码,来修改

System.loadLibrary("testdll");

对应的加载库

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值