1、java调用第三方dllvs创建的dll,java调用第三方dll内存错误,有图片。 。

隐式链接就是在程序开始执行时就将DLL文件加载到应用程序当中。隐式链接必须的文件:lib .
显式链接是应用程序在执行过程中随时可以加载DLL文件,也可以随时卸载DLL文件,这是隐式链接所无法作到的,所以显式链接具有更好的灵活性,对于解释性语言更为合适。不过实现显式链接要麻烦一些。在应用程序中用LoadLibrary或MFC提供的AfxLoadLibrary显式的将自己所做的动态链接库调进来,动态链接库的文件名即是上述两个函数的参数,此后再用GetProcAddress()获取想要引入的函数。自此,你就可以象使用如同在应用程序自定义的函数一样来调用此引入函数了。在应用程序退出之前,应该用FreeLibrary或MFC提供的AfxFreeLibrary释放动态链接库。
使用显式链接应用程序编译时不需要使用相应的Lib文件。另外,使用GetProcAddress()函数时,可以利用MAKEINTRESOURCE()函数直接使用DLL中函数出现的顺序号,如将GetProcAddress(hDLL,"Min")改为GetProcAddress(hDLL, MAKEINTRESOURCE(2))(函数Min()在DLL中的顺序号是2),这样调用DLL中的函数速度很快,但是要记住函数的使用序号,否则会发生错误。&
显式链接必须的文件:dll .
一、DLL的创建 (用.def文件创建动态连接库)
创建项目-&Win32-&Win32项目,名称:MyDLL-&选择DLL
1、新建头文件testdll.h
testdll.h代码如下:
#ifndef TestDll_H_
#define TestDll_H_
#ifdef MYLIBDLL
#define MYLIBDLL extern "C" _declspec(dllimport)
#define MYLIBDLL extern "C" _declspec(dllexport)
MYLIBDLL int Add(int plus1, int plus2);
//You can also write like this:
//extern "C" {
//_declspec(dllexport) int Add(int plus1, int plus2);
2、新建源文件testdll.cpp
testdll.cpp代码如下:
#include "stdafx.h"
#include "testdll.h"
#include &iostream&
int Add(int plus1, int plus2)
int add_result = plus1 + plus2;
return add_
3、新建模块定义文件mydll.def
mydll.def代码如下:
LIBRARY "MyDLL"
4、vs2008自动创建dllmain.cpp文件,它 定义了DLL 应用程序的入口点。
dllmain.cpp代码如下:
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
ul_reason_for_call,
LPVOID lpReserved
switch (ul_reason_for_call)
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
return TRUE;
} 最后,编译生成MyDLL.dll文件和MyDLL.lib文件。
二、DLL的使用(静态链接、隐式链接 &)
创建项目-&Win32控制台应用程序,名称:UseDLL。
将MyDLL.lib文件放在与UseDLL.exe文件的目录下。
创建源文件UseDll.cpp
UseDll.cpp代码如下:
// UseDll.cpp : 定义控制台应用程序的入口点。
#pragma comment (lib,"MyDLL.lib")
#include "stdafx.h"
#include &iostream&
extern "C" _declspec(dllimport) int Add(int plus1, int plus2);
//或者直接在工程的Setting-&Link页中设置导入MyDll.lib既可
int _tmain(int argc, _TCHAR* argv[])
int a = 20;
int b = 30;
cout&&"a+b="&&Add(a, b)&&
getchar();
运行结果如下:
三、DLL的使用(动态调用、显式链接)
创建项目-&Win32控制台应用程序,名称:UseDLL。
将MyDLL.dll文件放在与UseDLL.exe文件的目录下。
创建源文件UseDll.cpp
UseDll.cpp代码如下:&
// UseDll.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include &iostream&
#include &windows.h&
typedef int (*AddFunc)(int a,int b);
int _tmain(int argc, _TCHAR* argv[])
HINSTANCE hInstLibrary = LoadLibrary(_T("MyDLL.dll"));//注意此处必须有_T()函数。
if (hInstLibrary == NULL)
FreeLibrary(hInstLibrary);
cout&&"LoadLibrary error!"&&
getchar();
AddFunc _AddFunc = (AddFunc)GetProcAddress(hInstLibrary, "Add");
if (_AddFunc == NULL)
FreeLibrary(hInstLibrary);
cout&&"GetProcAddress error!"&&
getchar();
cout &&"a+b="&&_AddFunc(20, 30) &&
getchar();
FreeLibrary(hInstLibrary);
Cyper的笔记,第二步静态链接报如下错误
1&------ Build started: Project: testdll, Configuration: Debug Win32 ------
1&Linking...
1&testdll.obj : error LNK2019: unresolved external symbol __imp__Add referenced in function _wmain
1&C:\f\vsProject\Vc9.0\testdll\Debug\testdll.exe : fatal error LNK1120: 1 unresolved externals
1&Build log was saved at "file://c:\f\vsProject\Vc9.0\testdll\testdll\Debug\BuildLog.htm"
1&testdll - 2 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
// UseDll.cpp : 定义控制台应用程序的入口点。
#include "stdafx.h"
#include &iostream&
#pragma comment (lib,"MyDLL.lib")
extern "C" _declspec(dllimport) int Add(int plus1, int plus2);
//或者直接在工程的Setting-&Link页中设置导入MyDll.lib既可
int _tmain(int argc, _TCHAR* argv[])
int a = 20;
int b = 30;
cout&&"a+b="&&Add(a, b)&&
getchar();
} 把#prama这一行移到stdafx.h下面就没有错了(折腾了很久才试出来
& 开源中国(OSChina.NET) |
开源中国社区(OSChina.net)是工信部
指定的官方社区Java 调用Dll-中国学网-中国IT综合门户网站-提供健康,养生,留学,移民,创业,汽车等信息
Java 调用Dll
来源:互联网 更新时间: 9:37:18 责任编辑:王亮字体:
Java 中怎么能调用到dll中的函数呢?
关键是java中生的本地函数名参数和dll中的本地函数名参数一模一样。
这个程序是java中调用dll中的求和函数。
一,java代码部分操作
1.新建工程
2.DllTest.java代码
package com.aizizai.
public class DllTest {
System.loadLibrary(&hellodll&);
public static native int sum(int a, int b);
public static void main(String[] args) {
System.out.println(&sum(2,5) = & + sum(2, 5));
3. 生成头文件
Java调用dll测试\src&javac com/aizizai/calldll/DllTest.javaJava调用dll测试\src&javah com.aizizai.calldll.DllTest
二,VC利用前面的头文件生成dll。本文使用的是vs2010。
1. 创建项目
新建项目--& vc++ --& win32项目 --& 命名为hellodll --&应用程序类型:dll --&ok。
2. 添加头文件
/jdk/include/jni.h
/jdk/include/win32/jawt_md.h
/jdk/include/win32/jni_md.h
拷到项目目录下或者Vs的include目录下。
b. stdafx.h中添加
#include &com_aizizai_calldll_DllTest.h&
3. 在源文件中添加函数实现
// hellodll.cpp : 定义 DLL 应用程序的导出函数。
#include &stdafx.h&
JNIEXPORT jint JNICALL Java_com_aizizai_calldll_DllTest_sum
(JNIEnv *env, jclass ss, jint a, jint b){
return a+b;
4. 生成dll
生成 ---& 生成dll。
即可在项目的Debug目录下看到,hellodll.dll文件
把dll文件拷到 c:\windows目录下,运行java程序。ok。
程序下载地址:
相关文章:
上一篇文章:下一篇文章:
最新添加资讯
24小时热门资讯
Copyright © 2004- All Rights Reserved. 中国学网 版权所有
京ICP备号-1 京公网安备02号jna调用dll里的方法时报错,请看图片,这是c的函数,我使用java来调用_百度知道JNI使用技巧点滴
本文为在 32 位 Windows 平台上实现 Java 本地方法提供了实用的 示例、步骤和准则。本文中的示例使用 Sun Microsystems 公司创建的 Java Development Kit (JDK) 版本 &1.4.1。用 C 语言编写的本地代码是用 Microsoft Visual C++ 6.0编译器编译生成。
  近日,由于项目需要,要在WEB页面实现图像转换功能,而VC在图像转换方面有着得天独厚的优势。我们首先用VC封装出图像转换的DLL,然后用JAVA的本地化方法JNI调用用于图像转换的DLL,最后用JavaBean调用JNI生成的DLL。
  通过近几天在网上找资料和自己的摸索,收获很多,现总结如下,让以后做这方面的人少走弯路。
一. JAVA部分
 1. 无包的情况:
  实例一:
public class MyNative {
System.loadLibrary( &MyNative& );
public native static void HelloWord();
public native static String cToJava();
1)在JAVA程序中,首先需要在类中声明所调用的库名称System.loadLibrary( String libname );,在库的搜寻路 径中定位这个库。定位库的具体操作依赖于操作系统。在windows下,首先从当前目录查找,然后再搜寻”PATH”环境变量列出的目录。如果找不到该 库,则会抛出UnsatisfiedLinkError。
2)这里加载的是JNI生成的DLL,而不是其他生成的DLL的名称。 在这里,库的扩展名字可以不用写出来,究竟是DLL还是SO,由系统自己判断。
3) 还需要对将要调用的方法做本地声明,关键字为native。并且只需要声明,而不需要具体实现。 实现放在C中实现,稍后将做说明。
4)如果加了static,表明是静态方法。如果不加,表明是一般的方法。加与不加,生成的头文件中有一个参数不同。稍后将做说明。&
  现在开始编译它:
  用javac MyNative.h 编译它,生成对应的class文件。
  用javah MyNative ,就会生成对应的MyNative.h头文件。剩下的是就开始交给VC来完成了(我们用VC来实现对应的C实现部分)。
 2. 有包的情况:
  实例二:
package com.myN
public class MyNative {
System.loadLibrary( &MyNative& );
public native static void HelloWord();
public native static String cToJava();
其他与上面相同,就是在用javac和javah时有所不同。对于有包的情况一定要注意这一点,开始时我的程序始终运行都不成功,问题就出在这里。
  javac ./com/myNative/MyNative.java
  javah com.myNative.MyNative
上面一句就不用解释了。对下面的一句解释一下:本类的前面均是包名。这样生成的头文件就是:com.myNative.MyNative.h。
开始时,在这种情况下我用javah MyNative生成的头文件始终是MyNative.h。在网上查资料时,看见别人的头文件名砸那长,我的那短。但不知道为什么,现在大家和我一样知道为什么了吧。有时还需要带上路径。具体查看javah的语法。
二.C实现部分
  刚才用javah MyNative生成的MyNative.h头文件内容如下:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include &jni.h&
/* Header for class MyNative */
#ifndef _Included_MyNative
#define _Included_MyNative
#ifdef __cplusplus
extern &C& {
* Class: MyNative
* Method: HelloWord
* Signature: ()V
JNIEXPORT void JNICALL Java_MyNative_HelloWord (JNIEnv *, jclass);
* Class: MyNative
* Method: cToJava
* Signature: ()Ljava/lang/S
JNIEXPORT jstring JNICALL Java_MyNative_cToJava (JNIEnv *, jclass);
#ifdef __cplusplus
接下来,就是如何实现它了。其实,用JNI作出的东西也是DLL,被JAVA所调用。
在具体实现的时候,我们只关心两个函数原型:&
JNIEXPORT void JNICALL Java_MyNative_HelloWord(JNIEnv *, jclass);
和 JNIEXPORT jstring JNICALL Java_MyNative_cToJava(JNIEnv *, jclass);
现在让我们开始激动人心的第一步吧。在project里面选择win32 Dynamic-link Library,然后点击下一步,其余的取默认。如果不取默认的,将会有dllmain()函数。取空DLL工程的话,将无这个函数。我在这里取的是空。
然后选择new-&File-&C++ Source File,生成一个空*.cpp文件。我们把他取名为MyNative。把 JNIEXPORT void JNICALL Java_MyNative_HelloWord(JNIEnv *, jclass);和 JNIEXPORT jstring JNICALL Java_MyNative_cToJava(JNIEnv *, jclass);拷贝到CPP 文件中去。然后把头文件包含进来。
生成的MyNative.cpp内容如下:
#include &MyNative.h&
JNIEXPORT void JNICALL Java_MyNative_HelloWord (JNIEnv *env, jclass jobject)
printf(&hello word!\n&);
JNIEXPORT jstring JNICALL Java_MyNative_cToJava (JNIEnv *env, jclass obj)
  char str[]=&Hello,word!\n&;
  jstr=env-&NewStringUTF(str);
在编译前一定要注意下列情况。
注意:一定要把SDK中的include文件夹中(和它下面的win32文件夹下的头文件)的几个头文件拷贝到VC的include文件夹中。或者在VC的tools\options\directories中设置,把头文件给包含进来。
对程序的一点解释:
  1)前文不是说过,加了static和不加只是一个参数的区别吗。就是jclass的不同,不加static这里就是jobject。也就是 JNIEXPORT void JNICALL Java_MyNative_HelloWord(JNIEnv *env, &jobject obj)。
  2)这里JNIEXPORT和JNICALL都是JNI的关键字,表示此函数是要被JNI调用的。而 jstring是以JNI为中介使JAVA的String类型与本地的string沟通的一种类型,我们可以视而不见,就当做String使用(具体对应 见表一)。函数的名称是JAVA_再加上java程序的package路径再加函数名组成的(参见有包的情况)。参数中,我们也只需要关心在JAVA程序 中存在的参数,至于JNIEnv*和jclass我们一般没有必要去碰它。
  3)NewStringUTF()是JNI函数,从一个包含UTF格式编码字符的char类型数组中创建一个新的jstring对象。
   4) 以上程序片断jstr=env-&NewStringUTF(str);是C++中的写法,不必使用env指针。因为JNIEnv函数的C ++版本包含有直接插入成员函数,他们负责查找函数指针。而对于C的写法,应改为:jstr=(*env)-&NewStringUTF(env, str);因为所有JNI函数的调用都使用env指针,它是任意一个本地方法的第一个参数。env指针是指向一个函数指针表的指针。因此在每个JNI函数 访问前加前缀(*env)-&,以确保间接引用函数指针。
  在C和Java编程语言之间传送值时,需要理解这些值类型在这两种语言间的对应关系。这些都在头文件jni.h中,用typedef语句声明了这些类在目标平台上的代价类。头文件也定义了常量如:JNI_FALSE=0 和JNI_TRUE=1;
表一说明了Java类型和C类型之间的对应关系。
  表一 Java类型和C类型
Java类型 本地类型 描述
boolean jboolean C/C++8位整型
byte jbyte C/C++带符号的8位整型
char jchar C/C++无符号的16位整型
short jshort C/C++带符号的16位整型
int jint C/C++带符号的32位整型
long jlong C/C++带符号的64位整型e
float jfloat C/C++32位浮点型
double jdouble C/C++64位浮点型
& String jstring 字符串对象
Object[] jobjectArray 任何对象的数组
boolean[] jbooleanArray 布尔型数组
byte[] jbyteArray 比特型数组
char[] jcharArray 字符型数组
short[] jshortArray 短整型数组
int[] jintArray 整型数组
long[] jlongArray 长整型数组
float[] jfloatArray 浮点型数组
double[] jdoubleArray 双浮点型数组
现在开始对所写的程序进行编译。选择build-&rebuild all对所写的程序进行编译。点击build-&build MyNative.DLL生成DLL文件。
  也可以用命令行cl来编译。具体参看其他书籍。
  再次强调(曾经为这个东西大伤脑筋):DLL放置地方
  1) 当前目录。
  2) 放在path所指的路径中
  3) 自己在path环境变量中设置一个路径,要注意所指引的路径应该到.dll文件的上一级,如果指到.dll,则会报错。
下面就开始测试我们的所写的DLL吧(假设DLL已放置正确)。
public class mytest {
public static void main(String[] args) {
MyNative a=new MyNative();
a.HelloWord();
System.out.println(a.cToJava());
注意也要把MyNative.class放在与mytest.java同一个路径下。现在开始编译运行mytest,是不是在DOS窗口上输出:
  Hello word!
  Hello,world!
  以上是我们通过JNI方法调用的一个简单C程序。但在实际情况中要比这复杂的多。特别是在通过JNI调用其他DLL时,还有很多的地方需要注意。
  现在开始来讨论包含包的情况,步骤与上面的相同,只是有一点点不同。我们来看其中的一个函数。
JNIEXPORT void JNICALL Java_com_MyNative_MyNative_HelloWord (JNIEnv *env, jclass jobject) {
printf(&hello word!\n&);
我们来观察函数名称。函数的名称是JAVA_再加上java程序的package路径再加函数名组成的。现在这句话应该理解了吧。
我们也写一个程序来测试包含包的情况。程序略。
  javac ./com/MyNative/mytest.java
  java mytest
从 Java 程序调用C/C++ 代码的过程由六个步骤组成。
1)编写 Java 代码。我们将从编写 Java 类开始,这些类执行三个任务:声明将要调用的本机方法;装入包含本机代码的共享库;然后调用该本机方法。
2)编译 Java 代码。在使用 Java 类之前,必须成功地将它们编译成字节码。&
3)创建 C/C++ 头文件。C/C++ & 头文件将声明想要调用的本机函数说明。然后,这个头文件与 C/C++ 函数实现(请参阅步骤4)一起来创建共享库(请参阅步骤5)。
4)编写 C/C++ 代码。这一步实现 C 或 C++ 源代码文件中的函数。C/C++ 源文件必须包含步骤3 中创建的头文件。
5)创建共享库文件。从步骤 4 中创建的 C 源代码文件来创建共享库文件。 &&
6)运行 Java 程序。运行该代码,并查看它是否有用。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:143396次
积分:7315
积分:7315
排名:第2000名
原创:613篇
转载:15篇
(34)(68)(42)(10)(30)(15)(38)(64)(15)(12)(47)(43)(37)(90)(84)温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
阅读(4711)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_084069',
blogTitle:'Java调用DLL程序',
blogAbstract:'一、 生成C的头文件 \r\n1. 编辑Main.java public class Main \r\n{ \r\npublic native static int getStrNum(byte str[], int strLen); \r\n} \r\n2. 生成头文件 \r\n按win + r打开“运行”窗口,输入“cmd”,打开DOS控制台窗口。进入上面Main.java所在的目录中,输\r\n入: \r\njavac Main.java \r\njavah Main \r\n两条命令完成后会生成Main.h文件 \r\n二、 生成DLL \r\n1. 新建空工程 在VS中新建工程:Win32 Console Application,取名“MakeDLL”,选择空工程。新建后修改工程属性: ',
blogTag:'',
blogUrl:'blog/static/',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:4,
permalink:'blog/static/',
commentCount:0,
mainCommentCount:0,
recommendCount:0,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'踏实,诚实',
hmcon:'0',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}

我要回帖

更多关于 java jni调用dll 的文章

 

随机推荐