基于jni库Java调用C++的DLL的说明文档

基于jni库Java调用C++的DLL的说明文档

参照网上资料,我们以一个简单的事例讲述如何在window或者linux环境下,Java代码如何调用C++。本文档只测试了window下Java调用DLL是正确的,linux下的so并未验证,但是据资料说用同样的方法即可,不需要区分dll和so。

项目背景

现在有文件setNum.cpp文件,如下:

1
2
3
4
5
6
7
int i = 0;
int get(){
return i;
}
void set(int j){
i = j;
}

那我们如何用java去用set和get方法呢?下面我们来解决这个问题吧。

Java调用C++的方法

概括来说,我们需要做几件事:java采用jni对dll进行引用;基于jni,按照java新生成的.h文件重写编写cpp,并生成相应的新的dll。下面将结合代码详细讲述

1.基于jni,java对已有的dll引用
假设已有有setNum.cpp生成的dll,名为goodluck.dll,我们写testdll.java文件,如下,包括引用dll文件,以及用native定义setNum.cpp内部的方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class testdll 
{
static
{
System.loadLibrary("goodluck"); //此处引用的dll
}
public native static int get();
public native static void set(int i);

public static void main(String[] args)
{
testdll test = new testdll();
test.set(10);
System.out.println(test.get());
}
}

2.生成基于jni的新代码

1
2
javac testdll.java //此处生成class文件
javah testdll //此处生成.h文件

java
我们看一下testdll.h代码,请注意里面的文字解说。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class testdll */

#ifndef _Included_testdll
#define _Included_testdll
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: testdll
* Method: get
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_testdll_get
(JNIEnv *, jclass); // 此处是基于jni,对testdll.java里的方法进行重写,因此我们需要在cpp文件重写。

/*
* Class: testdll
* Method: set
* Signature: (I)V
*/
JNIEXPORT void JNICALL Java_testdll_set
(JNIEnv *, jclass, jint);

#ifdef __cplusplus
}
#endif
#endif

3.C/C++重写方法
按照testdll.h文件中的方法命名方式,重写testdll.cpp文件,如下:

1
2
3
4
5
6
7
8
9
#include "StdAfx.h"
#include "testdll.h"
int i = 0;
JNIEXPORT jint JNICALL Java_testdll_get(JNIEnv *, jclass){
return i;
}
JNIEXPORT void JNICALL Java_testdll_set(JNIEnv *, jclass, jint j){
i = j;
}

4.重新生成dll
我是用VC++生成的dll,我想工具是很多的,思路到了就可以啦~。
我在VC++新建了一个win32 Dynamic-Link Library简单的项目,也就是DLL项目,命名为goodluck(很明显抄袭人家,想上面网络资料的作者致谢!)。
将testdll.cpp里面的代码内容覆盖goodluck.cpp,这时候变异运行即可生成dll文件。

但是会出现一些问题,由于jni可能没引入,编译不过去。所以请将下图中jdk的include中的三个文件放在vc++相应的include文件下,在编译即可。
jni
vc

5.运行java文件
最后我们将goodluck项目中生成的goodluck.dll放在与testdll.java同级文件夹下即可。
goodluck
我们运行一下testdll.java文件

java testdll

成功啦

ejs的学习

表明目标:我要自己写一个hexo主题

用hexo建博客也有一段时间了,用的是别人的主题,总觉得很不爽,因此励志做一个自己的主题。hexo采用的ejs模板引擎,然后嘞,道路总是曲折的,学一下ejs啦~~~
Ps:今天重新由npm到hexo上传git整个流程走了一遍,详见我的文章:hexo使用安装教程

快速入门

js模板引擎

更深的考虑

hexo使用安装教程

npm和node安装

请官网下载nodejs.msi文件,里面整合了npm和nodejs。我的电脑系统是win7。
注意:因为npm模块管理器的镜像是在国外,因此超级慢,请用cnpm,走的是taobao镜像,如下代码,请在cmd里运行:

1
npm install cnpm -g --registry=http://registry.npm.taobao.org

hexo构建自己的博客

用cnpm安装hexo。

1
cnpm install hexo -g

然后初始化一个blog,如下

1
hexo init blog

进入blog文件下,下载所有依赖的模块

1
ncpm install

然后就ok了,你可以通过hexo server开启服务器,或者hexo new “文章名”新建文章,然后hexo generate 生成静态的页面。

github上传

对于新手必然是用github上托管代码或者作为服务器,那我们必然要做hexo上传github的绑定。
首先在_config.yml里面配置git地址,然后hexo deploy会自动创建.deploy_git文件夹,进去,git init,然后就可以提交啦~~~

js中有哪些内存泄露?我们如何解决呢?

内存泄漏指任何对象在您不再拥有或需要它之后仍然存在。
垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可回收。

  1. setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
  2. 闭包
  3. 控制台日志
  4. 循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)

小米前端面试,第一面

1 用过什么预编译, less有什么特性
2 H5首先存储, 还有什么特性
localStorage cookie seesionStorage
3 为什么语义化, 怎么语义化,有什么好处
4 内存泄露,闭包如何释放
5 优化,如何优化
6 用户体验
7 两列布局
8 继承, 原型链图

初识less

半年瞎忙活了,就找到了一只手的工作,算是安稳了,内心还是很纠结,里面有两个小人,黑人说去互联网吧,年轻,总要努力奋斗吧,你甘心在一个国企里,没有技术大牛可仰慕,没有潮流技术追赶,天天碌碌无为,有什么意思?白人在说,女孩子家家的,当什么码农,加班多压力大,而且还要嫁人照顾家庭,现在不是很好嘛,待遇不错,很清闲,没事的时候可以搞些副业神马的。啊,神啊,人生怎么过才能有意义,是努力奋斗?还是尽情享受?奋斗成功留名的也就那几个人,享受生活的就敢于平庸吗?什么是有意义,头疼~~~~吐槽一下,然后决定即使周围人不关心技术,我还是要继续学习!!重拾半年前的博客,电脑重装后由npm到github上传都走了一遍,不熟的人都来看看撒,说不定有帮助。

less是什么?

一种动态样式语言.
LESS 将 CSS 赋予了动态语言的特性,如 变量, 继承, 运算, 函数. LESS 既可以在客户端上运行 (支持IE 6+, Webkit, Firefox),也可以借助Node.js或者Rhino在服务端运行。

之前我们是针对样式, 直接写css, 很多颜色, 字体等重复, 我们也只能尽量整合, 因此很多并不认为css是一个语言, 因为是固定的。 那么less让css变的更像语言了。

为什么会有less?

  1. 通用组件, 例如各种内核都兼容的圆角效果或者下三角形,这种组件生成的CSS效果都是一样的,如果每个用到的都复制一份代码, 这样子代码复用性就会很差。 这样子我们可以想一下代码复用常用的模块~, 我们为何不把这个组件封装起来, 然后在调用? 就像bootstrap等各种框架内, 把常用的组件写死, 我们只要设置label或者class就行了。
  2. 常用属性的频繁更改:例如空间主题颜色更换,或者字体更换, 这时候我们不可能手动找到各个颜色地方去修改,要是有变量管着这些或者一个接口管着就行了, 我们只需要改一个接口值。
  3. 还有一个很玄乎的, 没看懂呢~,估计等用熟了就能理解吧。 如果html层级结构比较复杂,怎么结构化你的css,做到selector的精确打击。这个怕是很困难的吧。
    上边这些SASS和LESS都可以解决,而这还只是给CSS带来的最浅显的好处。

对应的应该是一下:
1:变量定义,@navColor:#96CDCD,这样后面就不用还去取样,查表之类的。
2:mixin,减少n多代码量。ps:带参数的更帅。
3:嵌套,逻辑清楚。
4:颜色函数。

less使用情况(个人情绪)

作为一个说一下感受啦~
我觉得一个人随意写写可以尝试用一下, 最难点我觉得应该是怎么判断哪些通用? 那些可以提炼出来,没用过就不怎么说啦, 借知乎的话~
1、less适合有css经验的人使用
2、less用于网站重构非常不错
3、less可用于写css框架

less语法与编译

1 客户端解析
在这个之前加载less文件

2 nodejs lessc
lessc 源文件 目的文件

3 借助第三方软件 koala
直接添加less文件夹, 然后会自动在相应目录下创建一个css文件夹进行解析

这样子客户端解析会浪费时间, 还是尽量在后台解析好, 然后传给前台

Enchanted by Taylor

Enchanted我觉得可以翻译成一见钟情撒~, 准备面试一周后,来一曲大家欣赏撒。

美丽的故事背景(我是很喜欢Adam哒)

Taylor Swift对Adam Young一见钟情,写下这首美丽缱绻的歌,自述自己萌生的情愫。
更令人惊奇的是,Adam Young听出了其中的密语A-D-A-M,并在2011年的情人节,改编了该歌曲做出了回应。
“我该会是第一个承认自己比较害羞的男孩吧,因为音乐才是我可以拿得出手的最真实生动的方式。我决定为你录一些东西——就作为对你新专辑里那首令我激动万分的歌曲的回应吧。”他写道,“你就像是一个从梦幻般的童话故事里走出来的公主,最重要的,我只想让你知道,我也对你着了迷。”–Adam Young
然而在Adam Young完成了歌曲的改编回应之后,Taylor Swift没有再回应Adam Young,这一点在Adam的访谈中被提到。
这首歌听来让人荡气回肠——不管你们有没有在一起,结局已不再重要。我心中挂念的一直是你,这才是我一生所念。

歌词(总是霉霉式, 虽然简单,但是在她的歌曲里面很不错哒)

there I was again tonight
forcing laughter, faking smiles
same old tired, lonely place
walls of insincerity
shifting eyes and vacancy
vanished when I saw your face
All I can say is it was enchanting to meet you
your eyes whispered “have we met?”
across the room, your silhouette
starts to make its way to me
the playful conversation starts
counter all your quick remarks like passing notes in secrecy
and it was enchanting to meet you
all I can say is I was enchanted to meet you
this night is sparkling, don’t you let it go
I’m wonderstruck, blushing all the way home
I’ll spend forever wondering
if you knew I was enchanted to meet you

MV很赞, 就是霉霉那个香水广告

歌词”I am wonderstruck blushing all the way home”中的wonderstruck一词,也成为了Taylor Swift同名香水的名字(Wonderstruck香水为伊丽莎白雅顿与Taylor Swift在2011年秋季合作推出的首支个人女性香水)。Wonderstruck原意指吃惊,惊讶不已,代表了瞬间让人吃惊,兴奋的回忆,用来表现遇到某人时的悸动心情。

针对浮动元素,怎么居中呢?

什么是浮动元素

w3c:由于浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样。

针对一个浮动元素,怎么居中(水平和垂直)?

这就有两种情况:
1、元素大小知道
元素大小即已知, 我们可以通过margin和left, top进行补偿, 使得元素可以居中。
known
known

2、元素大小不知道
元素大小未知, 我们通过margin auto自适应。 这里我们要补一下知识, 定位的布局取决于三个因素:元素的位置,元素的尺寸,元素的margin值。
没有设置尺寸和 margin 的元素会自适应剩余空间,位置固定则分配尺寸,尺寸固定边会分配 margin,都是自适应的。
IE7- 的渲染方式不同,渲染规则也不一样,他不会让定位元素去自适应。

unknown

怎么样子可以水平居中一个浮动元素?

当然采用上述的方法肯定是可行的, 但是我们要介绍一种新方法:一个盒子浮动 加一个relative的盒子在外面 然后把盒子设为absolute 然后定位:外面盒子向右偏移50% left 里面的向左偏移50% right。
unknown

怎么居中一个图片?

1、最简单的方式, display table-cell
display:table-cell属性指让标签元素以表格单元格的形式呈现,类似于td标签。目前IE8+以及其他现代浏览器都是支持此属性的,但是IE6/7只能对你说sorry了,这一事实也是大大制约了display:table-cell属性在实际项目中的应用。我们都知道,单元格有一些比较特别的属性,例如元素的垂直居中对齐,关联伸缩等,所以display:table-cell还是有不少潜在的使用价值的,虽说IE6/7不支持此属性,但是幸运的是,IE6/7一些乱糟糟的属性与渲染,我们可以其他方法实现同样或是类似的效果。
与其他一些display属性类似,table-cell同样会被其他一些CSS属性破坏,例如float, position:absolute,所以,在使用display:table-cell与float:left或是position:absolute属性尽量不用同用。设置了display:table-cell的元素对宽度高度敏感,对margin值无反应,响应padding属性,基本上就是活脱脱的一个td标签元素了

相关应用请参考博客

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<div class="imgDiv">
<img src="img.jpg">
</div>

.imgDiv{
width: 500px;
height: 200px;
border: 1px solid grey;
text-align: center;
display:table-cell; //因为table是默认居中显示的
vertical-align: middle;
}

```
![imgCenter](http://wearejq.github.io/img/floatCenter/imgCenter1.jpg)


2、理解vertical-align,添加span
但是上述会出现低版本不兼容问题, 那么为什么简单的vertical-align没有用呢?

利用vertical-align :该属性定义行内元素的基线相对于该元素所在行的基线的垂直对齐、所以这个需要把块级容易的基准线定位居中。

因此我们需要添加一个相应的基准线

``` bash
<div class="imgDiv">
<span></span>
<img src="ex.jpg">
</div>

.imgDiv{
width: 500px;
height: 200px;
border: 1px solid grey;
text-align: center;
}
.imgDiv img{
vertical-align: middle;
}

.imgDiv span{
height: 100%;
display: inline-block;
vertical-align: middle;
}

结果如图:
imgCenter

###结论
关乎定位, 还真是很有学问, 其中table-cell只是浅尝辄止, 还有很多问题没有看, 当然关于居中有很多方法, 见仁见智啦。

什么是脱离文档流?有哪些?

先引用一段W3C的文档:
9.3 Positioning schemes
In CSS 2.1, a box may be laid out according to three positioning schemes:

  1. Normal flow. In CSS 2.1, normal flow includes block formatting of block-level boxes, inline formatting of inline-level boxes, and relative positioning of block-level and inline-level boxes.
  2. Floats. In the float model, a box is first laid out according to the normal flow, then taken out of the flow and shifted to the left or right as far as possible. Content may flow along the side of a float.
  3. Absolute positioning. In the absolute positioning model, a box is removed from the normal flow entirely (it has no impact on later siblings) and assigned a position with respect to a containing block.

An element is called out of flow if it is floated, absolutely positioned, or is the root element. An element is called in-flow if it is not out-of-flow. The flow of an element A is the set consisting of A and all in-flow elements whose nearest out-of-flow ancestor is A.

来源:Visual formatting model

脱离文档流就不占据空间了吗?

可以这么说。更准确地一点说,是一个元素脱离文档流(out of normal flow)之后,其他的元素在定位的时候会当做没看见它,两者位置重叠都是可以的。

脱离文档流是不是指该元素从dom树中脱离?

不是,用浏览器的审查元素就可以看到脱离文档流的元素(例如被float了)依然会出现在dom树里,下面的截图里也可以看到。

下面看一下例子:
下文中文档的HTML代码如下:

<body>
    <div id="outofnormal">
        Out of normal: 
        Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sequi esse impedit autem praesentium magni culpa, amet corporis, veniam consequatur voluptates temporibus. Voluptates eius similique asperiores cupiditate fugit hic atque quisquam?
    </div>
    <h2>Normal Content</h2>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Nostrum praesentium nam tempora beatae quis nobis laboriosam alias aliquid, tenetur exercitationem. Odio, aperiam, illo! Eveniet natus dignissimos architecto velit eligendi id!</p>
    <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Rem reprehenderit velit nam delectus distinctio at unde aliquid officia illo, tempore vitae et incidunt non, ut eos nesciunt quaerat. Enim, minus.</p>
</body>

CSS代码如下,为了看得更清楚,加一个padding

#outofnormal {
    width: 200px;
    background-color: cyan;
    padding: 10px;}

###normal flow 正常文档流
要被玩的div:
跟在后面的h2:
可以看到两者是垂直排列,padding互相顶着。3D视图的话就是这样,大家排排坐:
normal
normal
normal

浮动

加上float:left了之后,蓝色的div就脱离文档流了,变成了这样:
因为蓝色的div脱离了文档流,跟在后面的h2和p的盒子都当做没看到这个div的样子去定位,所以他们都顶着浏览器左边和顶部的边框。但是有趣的是,h2和p里面的文本(属于content flow)却都看到了这个被float的div,在自己的盒子里往右推,飘到了蓝色div的边上。这就是float的特性,其他盒子看不见被float的元素,但是其他盒子里的文本看得见。
3D视图的话就是这样。
float
float
float
为什么能插呢?因为蓝色div被旁边的盒子无视了呀~

absolute positioning。

删掉float: left,加上postion: absolute。和float一样的是,旁边的盒子无视了蓝色div的存在,也是顶着左边边框定位。但是~ 文本也无视了蓝色div的存在,顶着左边边框定位!
3D视图下也是成功无视之,插入~
position
position
position
总结:
脱离文档流,也就是将元素从普通的布局排版中拿走,其他盒子在定位的时候,会当做脱离文档流的元素不存在而进行定位。需要注意的是,使用float脱离文档流时,其他盒子会无视这个元素,但其他盒子内的文本依然会为这个元素让出位置,环绕在周围。而对于使用absolute positioning脱离文档流的元素,其他盒子与其他盒子内的文本都会无视它。