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方法里通过解密判断,如果为合法用户则无 ...
随机推荐
- Spark Streaming简介及原理
简介: SparkStreaming是一套框架. SparkStreaming是Spark核心API的一个扩展,可以实现高吞吐量的,具备容错机制的实时流数据处理. 支持多种数据源获取数据: Spark ...
- sql-server安装
ubuntu安装sql-server https://docs.microsoft.com/zh-cn/sql/linux/quickstart-install-connect-ubuntu?view ...
- 个人博客作业Week2(9月30日)
一.是否需要有代码规范 1.这些规范都是官僚制度下产生的浪费大家的编程时间.影响人们开发效率, 浪费时间的东西. 这些规范并不是一开始就有的,也不是由某个人规定的,代码规范是程序员们在不断地编程实践过 ...
- Zookeeper 3.4.8分布式安装
1.机器信息 五台centos 64位机器 2.集群规划 Server Name Hadoop Cluster Zookeeper Ensemble HBase Cluster Hadoop01 ...
- JAVA链表中迭代器的实现
注:本文代码出自<java数据结构和算法>一书. PS:本文中类的名字定义存在问题,Link9应改为Link.LinkList9应该为LinkList.由于在同包下存在该名称,所以在后面接 ...
- vuejs基础
**### 数据与方法 // 我们的数据对象 var data = { a: 1 } // 该对象被加入到一个 Vue 实例中 var vm = new Vue({ data: data }) // ...
- C#-ToString格式化
Int.ToString(format): 格式字符串采用以下形式:Axx,其中 A 为格式说明符,指定格式化类型,xx 为精度说明符,控制格式化输出的有效位数或小数位数,具体如下: 格式说明符 说明 ...
- 二维数组转化为一维数组 contact 与apply 的结合
将多维数组(尤其是二维数组)转化为一维数组是业务开发中的常用逻辑,除了使用朴素的循环转换以外,我们还可以利用Javascript的语言特性实现更为简洁优雅的转换.本文将从朴素的循环转换开始,逐一介绍三 ...
- org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing XML document from class path resource [applicationContext.xml]; nested exception is java.io.FileNotFoundException: c
//这个是 配置文件放错了地方 org.springframework.beans.factory.BeanDefinitionStoreException: IOException parsing ...
- ubuntu在windows下的wubi安装
转自:http://mp.weixin.qq.com/s?__biz=MjM5NjYxNjU0OQ==&mid=200664819&idx=2&sn=25719890570b1 ...