code::Blocks生成的dll 在 java jni 调用遇到的问题
Test.java
__________________________________
public class Test
{
public static native void p();
public static void main(String[] args)
{
System.loadLibrary("TestDll");
p();
}
}
javac Test.java
javah -jni Test //命令生成的test.c头文件
/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
/* Header for class Test */
#ifndef _Included_Test
#define _Included_Test
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: Test
* Method: p
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_Test_p
(JNIEnv *, jclass);
#ifdef __cplusplus
}
#endif
#endif
testdll.c (将 c:\jdk\bin下面的 jni.h 和 jni_md.h 复制到当前c程序的文件夹里)
________________________________
#include "jni.h"
#include "test.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_Test_p(JNIEnv *env, jobject obj)
{
printf("Hello world!\n");
return;
}
用code::Blocks生成的dll,使用DLL Export Viewer查看其函数名是Java_Test_p@8。
cmd> java Test 抛出错误:
java.lang.UnsatisfiedLinkError: Test.p()V
___________________________________________
解决的第1种方法:
在testdll.h文件中把"Java_Hello_p"函数前的"JNICALL"去掉,重编dll就能测试通过。(注: #define JNICALL __stdcall),网上的查到的资料如下:
HTML code
stdcall的调用约定意味着:1)参数从右向左压入堆栈,2)函数自身修改堆栈 3)函数名自动加前导的下划线,后面紧跟一个@符号,其后紧跟着参数的尺寸。
___________________________________________
解决的第2种方法:@silenceburn (http://topic.csdn.net/u/20110216/15/d85cf526-beb9-4a36-b6c2-7ade7f1eb01d.html)
正好手边有codeBlocks,就测试了一下,的确会有LZ说的问题,
放狗搜了搜,是因为JNI想要VC风格的函数声明,但是CodeBlocks默认的GCC编译器生成的是GCC风格的
需要用编译选项修改生成风格,8L的兄弟说的是对的。
修改的位置在CodeBlocks的工程右键properties - Build Targets - Build Options - Linker Setting - Other Linker Options ,加入 -Wl,--kill-at 即可。我在我本机已经测试通过。
___________________________________________
在测试通过java传字符串到c写的dll时,发现在c程序中打印出来的中文会出现乱码情况,在百度搜索后找到一个解决方法:
#include "jni.h"
#include "test.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
char* jstringToWindows( JNIEnv *env, jstring jstr );
jstring WindowsTojstring( JNIEnv* env, char* str );
JNIEXPORT void JNICALL Java_Test_p(JNIEnv *env, jobject obj)
{
printf("Hello world!\n");
return;
}
//通过java传字符串过来
JNIEXPORT void JNICALL Java_Test_abcd(JNIEnv *env, jobject obj, jstring p)
{
const char * str = jstringToWindows( env, p );
printf( "%s\n" , str);
/*
如果把上句改为下句,C接收Java字符串时将出现乱码:
//const char* str = (*env)->GetStringUTFChars(env, p, 0);
//printf("%s",str);
*/
}
//需要用一下2个函数做编码格式转换
char* jstringToWindows( JNIEnv *env, jstring jstr )
{
int length = (*env)->GetStringLength(env,jstr );
const jchar* jcstr = (*env)->GetStringChars(env,jstr, 0 );
char* rtn = (char*)malloc( length*2+1 );
int size = 0;
size = WideCharToMultiByte( CP_ACP, 0, (LPCWSTR)jcstr, length, rtn,(length*2+1), NULL, NULL );
if( size <= 0 )
return NULL;
(*env)->ReleaseStringChars(env,jstr, jcstr );
rtn[size] = 0;
return rtn;
}
jstring WindowsTojstring( JNIEnv* env, char* str )
{
jstring rtn = 0;
int slen = strlen(str);
unsigned short* buffer = 0;
if( slen == 0 )
rtn = (*env)->NewStringUTF(env,str );
else
{
int length = MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, NULL, 0 );
buffer = malloc( length*2 + 1 );
if( MultiByteToWideChar( CP_ACP, 0, (LPCSTR)str, slen, (LPWSTR)buffer, length ) >0 )
rtn = (*env)->NewString( env, (jchar*)buffer, length );
}
if( buffer )
free( buffer );
return rtn;
}
code::Blocks生成的dll 在 java jni 调用遇到的问题的更多相关文章
- Code::Blocks生成的EXE文件执行错误解决:The program can't start because libgcc_s_dw2-1.dll is missing
想用C++弄个简单东东,看有没有可行性, 开发软件,微软的太大太肿,就选用了Code::Blocks. 测试HELLO时,在工程环境中没问题的,但生成的EXE执行有问题, 报什么 libgcc_s_d ...
- Java JNI调用c语言的dll测试
最近复习C语言和java语言(10年没用了,温习一下),用JNI调用C语言的dll测试,以前没做过,在网上找了很多,总结如下: 环境:windows 10(64位) + JDK(32位,版本1.7.0 ...
- java jni 调用c语言函数
今日在hibernate源代码中遇到了native关键词,甚是陌生,就查了点资料,对native是什么东西有了那么一点了解,并做一小记. native关键字说明其修饰的方法是一个原生态方法,方法对应的 ...
- java jni 调用c++ opencv代码成功范例
java上建立接口定义 package com.dtk; public class Rec { public native String RecImage(String src); public st ...
- java jni调用
http://www.cnblogs.com/mandroid/archive/2011/06/15/2081093.html
- 使用code::blocks编译windows的dll链接库
因为机子上没有安装Visual Studio,所以找到了一种通过code::blocks编译dll的方式,踩到的坑是code::blocks默认的compiler是32位的,这样编译出的dll也是32 ...
- Java採用JNI调用VC++生成的dll(Java与C++交互)
应项目需求,须要android调用java,java再调用C++实现android一个图片匹配的功能,我们作为java组须要和C++和Android进行交互.以下是java和C++採用JNI的方式进行 ...
- Eclipse、MinGW、JNI编写C++生成dll, Java端调用的完整示例(附java.lang.UnsatisfiedLinkError解决方法)
Eclipse.MinGW.JNI编写C++生成dll, Java端调用的完整示例(附java.lang.UnsatisfiedLinkError解决方法) 问题背景:之前的JNI编程都是基于And ...
- Java通过JNI调用dll详细过程(转)
源:Java通过JNI调用dll详细过程 最近项目有这样一个需求,在已有的CS软件中添加一个链接,将当前登录用户的用户名加密后放在url地址中,在BS的login方法里通过解密判断,如果为合法用户则无 ...
随机推荐
- C_数据结构_快速排序
# include <stdio.h> void QuickSort(int * a, int low, int high); int FindPos(int * a, int low, ...
- left join 右表数据不唯一的情况解决方法
https://blog.csdn.net/u010089432/article/details/52165026
- 对MSF八个原则的思考
第一个原则,也是MSF中最基础的一个原则,推动信息共享与沟通.这个原则的一个特点是,对于团队成员的所有工作,都会被记录下来,包括走了弯路的.出现bug但已调试解决的部分.对于新加入团队的成员或者以前没 ...
- Linux内核及分析 第七周 可执行程序的装载
实验步骤 1. 更新menu,用test.c覆盖test_exec.c 2. 把init 和 hello 放到了rootfs.img目录下,执行exec命令的时候自动加载了hello程序 3. 执行e ...
- s标签s:if和s:set实现一个表格显示为多个表格
1.首先本来这个表格是这样的 2.这时候代码是这样的 <table cellpadding="4"> <tr> <th>指标点</th&g ...
- github个人作业
信息学院本科生课程设计 题目 文件加密和解密 课程名称 面向对象程序设计课程设计 课程编号 X031749 所在专业 计算机科学与技术 所在班级 计科高职13-3 ...
- css3-盒模型新增属性
box-shadow:跟text-shadow类似,可多层叠加 box-shadow:[inset] x y blur [spread] color inset:投影方式,inset内投影,不加参数外 ...
- jeecg 主-附表生成代码例子
jeecg 主-附表生成代码例子 - CSDN博客https://blog.csdn.net/u010411264/article/details/51243277 JEECG Online Codi ...
- Rabbitmq vs. kafka
https://mp.weixin.qq.com/s/2i_9TWoF3TsJvG6Dj_75vw http://www.cnblogs.com/valor-xh/p/6348009.html htt ...
- const修饰符与函数
一.用const修饰函数的参数 函数参数类型前加const指明该参数为常量,在函数内部不可改变. void func(const int x) { //x不可以在内部进行赋值等操作. } 注:当参数为 ...