当前位置:  编程技术>移动开发
本页文章导读:
    ▪NDK开发环境筹建_r8(转贴)        NDK开发环境搭建_r8(转贴) NDK开发环境搭建_r8 本文主内容: 1、  Android NDK 安装 2、  安装Cygwin与使用NDK编译 3、  在Eclipse中集成C/C++开发环境CDT 4、  安装Sequoyah插件 5、  JNI编译环境配置  .........
    ▪ LLVM compiler 4.0带到的Objective-C新语法特性        LLVM compiler 4.0带来的Objective-C新语法特性 LLVM 是 Low Level Virtual Machine (低级虚拟机)的简称,这个库提供了与编译器相关的支持,可以作为多种语言编译器的后台来使用。能够进行程序语言的.........
    ▪ [Open SSL[原]]取得文件信息摘要       [Open SSL[原]]获得文件信息摘要 #include <openssl/rsa.h> #include <openssl/evp.h> #pragma comment(lib, "libeay32.lib") DWORD ReadBufferFromFile(LPCSTR lpFileName, PBYTE pBuffer, PDWORD pdwLength) { if (NULL == lpFileName .........

[1]NDK开发环境筹建_r8(转贴)
    来源: 互联网  发布时间: 2014-02-18
NDK开发环境搭建_r8(转贴)

NDK开发环境搭建_r8

本文主内容:

1、  Android NDK 安装

2、  安装Cygwin与使用NDK编译

3、  在Eclipse中集成C/C++开发环境CDT

4、  安装Sequoyah插件

5、  JNI编译环境配置

 

本文建立在已经完成Android开发环境搭建的基础上。其基础环境至少需要包含以下内容:

1、  JDK

2、  Eclipse

3、  Android SDK and ADT

可以参考我之前的“Android开发环境搭建”。

一、Android NDK 安装与配置

下载Android NDK。下载地址:http://developer.android.com/tools/sdk/ndk/index.html

下载后解压缩到你的工作目录,例如:D:\Java\android-ndk-r8,结果如下图:

 

注意:samples下面包含几个实例开发演示项目,第一次接触NDK开发,建议先从示例开始。

      docs内是技术文档,英语能力强的可以研究研究。

二、安装Cygwin与使用NDK编译

由于NDK开发大都涉及到C/C++在GCC环境下编译、运行,所以在Windows环境下,需要用Cygwin模拟Linux编译环境。

下载:

Cygwin的下载地址:http://www.cygwin.com/

点击右上角的“setup.exe”即可下载。

安装:

         第一步:运行setup.exe程序,直接点击Next进入下一步。

第二步:选择安装方式。第一次可以采用Direct Connection在线下载安装,如有现成的离线包,可以选择离线安装(Install from Local Directory)。

第三步:选择安装目录。比如D:\Java\Cygwin,注意此目录是指Cygwin最终的安装目录,不是下载文件暂存目录。

第四步:设置本地包暂存路径。暂存目录默认是放到setup.exe的同级目录下,建议放到指定的文件夹,如D:\Cygwin_install_file。安装完成后把这个文件夹打包备份,以后再配置时不用重新下载。

第五步:设置网络连接方式。这个目前河蟹没爬过来,选第一个即可。

第六步:选择下载站点地址。据说国内163站点的速度不错,我也是用的这个。

第七步:等待加载安装项载入,选择安装项。点击Devel-Default,使之变成Devel-Install,展开后可以看到其下的子项被选中了(网上多数教程都说选中某12个包,找起来太坑爹了,直接全下载了吧,全选多了150M左右)。此界面其他设置都不用动。

第八步:等待下载完成。下载完成时间决定于你选择的安装包数量及网络连接速度,安装我安装的版本,约983M,下载完成后会自动安装到上文设置的安装目录,安装也要时间的,总时间较长,去吃个饭没啥问题。

提醒:第四步的备份建议,尽量去做。如果有备份,第二步中选择离线安装。

验证:

运行安装目录下的“Cygwin.bat”,第一次运行时,它会自动创建用户信息,用户信息存放在“.\Cygwin\home”中。

在运行“Cygwin.bat”打开的命令行窗口输入:“cygcheck -c cygwin”命令,会打印出当前Cygwin的版本和运行状态,如果status是ok的话,则cygwin运行正常。

分别输入:“make –v”和,“gcc –v”命令如果检测成功,会有make和gcc相关版本信息打印出来。

设置NDK路径:

在windows的系统环境变量中添加NDK的路径。使用“/cygdrive/d/Java/android-ndk-r8”这种Linux风格路径,如果使用Windows下的“D:\Java\android-ndk-r8”,Cygwin在编译时会发出警告。

 

         运行Cygwin命令行,可以直接使用此环境变量,当然也可以手动的cd到该目录:

 

使用NDK编译程序:

现在我们用安装好的NDK来编译一个NDK提供的sample程序hello-jni(我的目录位于:D:\Java\android-ndk-r8\samples\hello-jni)。

         第一步:运行Cygwin,配置环境变量后可输入“cd $ndk/samples/hello-jni/”,未配置则输入命令“cd /cygdrive/d/java/android-ndk-r8/samples/hello-jni”,进入到“hello-jni”工程目录。

 

         第二步:编译。输入命令“$ndk/ndk-build”命令即可编译。ndk-build是调用ndk的编译程序。

关于下面的错误,我没遇到,但是前人有总结,记录如下:

错误:Android NDK: Host 'awk' tool is outdated。

解决方法:打开目录“D:\Java\android-ndk-r8\prebuilt\windows\bin\”,删除awk.exe(为保险起见请先备份)。

 

         第三步:到”…/hello-jni/libs/armeabi“目录下看有没有生成的.so文件,如果有,你的ndk就运行正常啦!

 

导入NDK的hello-jni示例到Eclipse中:

         第一步:在Eclipse中新建一个Android工程HelloJni。在Create Android Project时勾选“Create project from existing source”,Location中填“D:\Java\android-ndk-r8\samples\hello-jni” (注意:在选择API level时需要选择1.5或更高的版本)。

         第二步:直接以Android Aplication运行。这里要注意,你之前在使用NDK编译程序时要把这个hello-jni编译过并产生了.so文件,此处才能运行起来。

 

三、在Eclipse中集成C/C++开发环境CDT

         CDT的安装可以使我们在一个工程中,同时开发基于C/C++的Native代码和基于Java语言的壳,之后的配置还可以使得一次编译两部分代码。

下载:

         下载地址:http://www.eclipse.org/cdt/downloads.php

说明:

Eclipse C/C++ IDE Indigo SR2:是带CDT的Eclipse开发环境。

p2 software repository:在线安装的地址。(似乎被河蟹爬了)

cdt-master-8.0.2.zip:这个是CDT的离线安装包。(推荐使用这个,保留离线包,复用)

离线安装:

         Eclipse -> Help -> Install New Software,点击add。Name:随意,建议使用好记的“CDT_版本”。Location:点击Archive,定位到下载的“cdt-master-8.0.2.zip”文件。

         错误:

如果Location的下面出现“Duplicate location”错误,请到Window -> preferences -> Install/Update -> Avaliable Software Site中找到该条,remove之。

验证:

         安装完成后,在Eclispe中新建一个项目,如果出现了C/C++项目,则表明CDT插件安装成功了。

 

四、安装Sequoyah插件

Sequoyah插件用于设置Android工程对Native开发的支持。

官方网址:http://www.eclipse.org/sequoyah/downloads/

在线安装:

         官网提供了用于在线安装的Update Site地址以及安装包的下载地址。貌似安装包才1M多,在线安装也没被河蟹爬过,直接在线安装了。勾选全部列出的可安装项并完成安装。

Location:http://download.eclipse.org/sequoyah/updates/2.0/

 

注意:

在安装界面不要勾选“Group items by category”复选框,默认是勾选的,出现了列表为空(There are no categorized items)的情况。

 

配置:

         安装完Sequoyah插件后,为Android配置NDK路径。

         在“window –> preferences ->Android -> 本机开发”中添加NDK的路径。

 

验证:

         右键之前建立的“HelloJni”项目,在“Android Tools”选项中包含“Add Native Support…”选项即成功。

五、JNI编译环境配置

         仍旧以之前建立的“HelloJni”为例,到目前为止,如果我们修改“/HelloJni/jni/hello-jni.c”文件,动态链接库libhello-jni.so文件却不会被重新编译生成。这是因为我们没有给JNI项目添加它需要的编译配置和依赖库。现在我们来配置它。

         第一步:转换工程。点击“文件 -> 新建 -> 其他”(快捷键:Ctrl+N)。选择“C/C++”下的“Convert to a C/C++ Project(Adds C/C++ Nature)”。进入“下一步”。

 

         第二步:选中你刚才建的“HelloJni”工程,下面左边选“Makefile project”右边选“Cygwin GCC”。确定后提示的“透视图”不清楚是什么,点击“是”即可。

 

         第三步:在“HelloJni”工程上右键,选择“属性”。配置“C/C++ Build”和“C/C++ General ->  Paths and Symbols”。

         C/C++ Build:点击“C/C++ Build”,在右边的“Builder Settings”中去掉默认勾选的“Use default build command”复选框。设置Build command为“bash D:\Java\android-ndk-r8\ndk-build”。

         C/C++ General ->  Paths and Symbols:在Includes下add新的GNU C依赖路径。此“HelloJni”工程需要“D:\Java\android-ndk-r8\platforms\android-8\arch-arm\usr\include”即可,以后根据不同项目选择不同的依赖库。 

 

验证:

         将“/HelloJni/jni/hello-jni.c”中的字符串“Hello from JNI !”如改为“Hello JNI from Baron!”,运行后在模拟器上输出的字符串改变即说明配置成功。 


    
[2] LLVM compiler 4.0带到的Objective-C新语法特性
    来源: 互联网  发布时间: 2014-02-18
LLVM compiler 4.0带来的Objective-C新语法特性

LLVM 是 Low Level Virtual Machine (低级虚拟机)的简称,这个库提供了与编译器相关的支持,可以作为多种语言编译器的后台来使用。能够进行程序语言的编译期优化、链接优化、在线编译优化、代码生成。

LLVM是构架编译器(compiler)的框架系统,以C++编写而成,用于优化以任意程序语言编写的程序的编译时间(compile-time)、链接时间(link-time)、运行时间(run-time)以及空闲时间(idle-time),对开发者保持开放,并兼容已有脚本。

 

Xcode 4.4中LLVM compiler 4.0带来的Objective-C新语法特性

1.使用的方法代码放置的位置顺序无关,没在.h文件中声明的方法,有的时候如果方法不在前面,可能会有警告。新的编译器会先扫描代码中的方法然后在编译,方便很多。

2.@property对于使用Objective-C的程序员来说是相当熟悉的,property方便自动生成变量的getter 和setter。在.h文件中声明之后,还要在.m文件中加上@synthesize关键字,这样才能完成自动getter 和setter的过程。

比如说,我在.h文件中写了

@property (strong, nonatomic) NSDictionary *order;

我还要去对于的.m文件中写上

@synthesize order;

是不是感觉很多余啊?现在在语法新特性中不用写这行代码了,新版的编译器帮你实现这行代码。也是说,你在.h文件中声明order属性后,就可以直接在实现文件中使用该属性的getter和setter方法,编译器还会根据属性的可读和可写自动判断是否提供setter方法。智能多了。

3.更多新特性参考:http://lxmdrw.blog.163.com/blog/static/2771697120128195203370/

 

 

 

__unsafe_unretain、__strong、__weak、__autoreleasing是出现在 LLVM 编译器 3.0版本之后。而__unsafe_unretain、__strong、__autoreleasing可以在不使用ARC(自动参考计数)可用。在ARC下,默认的指针都是__strong属性。这意味着一个对象赋值给另外一个指针,那么只要指针参考了该对象,该对象就会一直保持。这对于大部分对象都实用,但是这可能会导致retain cycle。例如,你拥有一个对象包含了另外了一个实例变量对象,但是第二个对象又把前一个对象作为它的委托,那么这两个对象将不会被释放。


因为上面的原因,所以才有了__unsafe_unretain和__weak限定符存在。他们通常用来修饰delegate,即定义一个delegate的属性时,使用__unsafe_unretain和__weak来修饰,然后通过使用__unsafe_unretain和__weak来单独标记实例变量。这意味着delegate实例变量将仍然能够指向第一个对象,但是它不会导致保留第一个对象,因此打破了retain cycle,而能够释放两个对象


除了delegate,__unsafe_unretain和__weak修饰符也还能避免你的代码出现retain cycle。Leaks instrument现在包含了一个cycle视图,能够发现你的应用中的retain cycle,并图像显示出来。


__unsafe_unretain和__weak都能避免retain cycle,但是他们也有一些细微的不同。对于__weak,当释放指针指向的对象时,该对象的指针将转换为nil,这是比较安全的行为。而__unsafe_unretain,正如其名称隐藏的含义,尽管释放指针指向的对象时,该指针将继续指向原来的内存。这将会导致应用crash,所以是unsafe。


为什么我们仍要使用__unsafe_unretain呢?这是因为__weak直到iOS5.0以及lion之后才出现。


而__autoreleasing 的英文解释为:to denote arguments that are passed by reference (id *) and are autoreleased on return,即主要是在引用传参时使用。 

 


 


    
[3] [Open SSL[原]]取得文件信息摘要
    来源: 互联网  发布时间: 2014-02-18
[Open SSL[原]]获得文件信息摘要
#include <openssl/rsa.h>
#include <openssl/evp.h>
#pragma comment(lib, "libeay32.lib")

DWORD ReadBufferFromFile(LPCSTR lpFileName, PBYTE pBuffer, PDWORD pdwLength)
{
    if (NULL == lpFileName
        || NULL == pBuffer
        || NULL == pdwLength)
    {
        return -1;
    }

    //----------------------------
    // 0. Local variables declaration
    DWORD nbytes = 0;
    HANDLE hFile = NULL;
    DWORD dwBufferLen = *pdwLength;
    DWORD dwFileLen = 0;

    //----------------------------
    // 1. Read certificate to buff
    //    This certificate contains certificate info (CI) and digital signature (DS)
    hFile = CreateFileA(lpFileName, GENERIC_READ, 0, NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );

    if (hFile == INVALID_HANDLE_VALUE) 
    {
        return -1;
    }

    dwFileLen = GetFileSize(hFile, NULL);
    *pdwLength = dwFileLen;

    if (dwBufferLen >= dwFileLen)
    {
        ReadFile(hFile, pBuffer, dwFileLen, &nbytes, NULL);
    }
    else
    {
        if (hFile != NULL)
        {
            CloseHandle(hFile);
        }

        return -1;
    }

    if (hFile != NULL)
    {
        CloseHandle(hFile);
    }

    return 0;
}

void FlipBuffer(unsigned char *pBuf, unsigned long ulLen)
{
    if(0 == ulLen)
    {
        return;
    }

    //char tmp;
    unsigned char ucTemp;
    for(unsigned long i = 0; i < ulLen >> 1; ++i)
    {
        ucTemp = pBuf[i];
        pBuf[i] = pBuf[ulLen - i - 1];
        pBuf[ulLen - i - 1] = ucTemp;
    }
}

void MSkeyConvertToOpenSSLKey(const char* filename, RSA& Rsa)
{
    if (NULL == filename)
    {
        return;
    }

    unsigned char byPrivateKeyBlob[2324] = {0};
    DWORD dwPrvKeySize = sizeof(byPrivateKeyBlob);
    ReadBufferFromFile(filename, byPrivateKeyBlob, &dwPrvKeySize);

    BYTE *pszPubBlob = byPrivateKeyBlob;
    RSAPUBKEY *rsapubkey = reinterpret_cast<RSAPUBKEY *>(pszPubBlob + sizeof(PUBLICKEYSTRUC));

    BYTE *pE = (BYTE *)&(rsapubkey->pubexp);
    DWORD dwElen = sizeof(DWORD);

    DWORD dwModulusLen = rsapubkey->bitlen / 8;
    DWORD dwPrimeLen = rsapubkey->bitlen/16;
    BYTE *pOffset = pszPubBlob + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY);

    BYTE *pN = pOffset;
    pOffset += dwModulusLen;

    BYTE *pP = pOffset;
    pOffset += dwPrimeLen;

    BYTE *pQ = pOffset;
    pOffset += dwPrimeLen;

    BYTE *pP1 = pOffset;
    pOffset += dwPrimeLen;

    BYTE *pQ1 = pOffset;
    pOffset += dwPrimeLen;

    BYTE *pPQ = pOffset;
    pOffset += dwPrimeLen;

    BYTE *pD = pOffset;
    pOffset += dwModulusLen;

    FlipBuffer(pE, dwElen);
    FlipBuffer(pN, dwModulusLen);
    FlipBuffer(pP, dwPrimeLen);
    FlipBuffer(pQ, dwPrimeLen);
    FlipBuffer(pP1, dwPrimeLen);
    FlipBuffer(pQ1, dwPrimeLen);
    FlipBuffer(pPQ, dwPrimeLen);
    FlipBuffer(pD, dwModulusLen);

    while(0x00 == *pE)
    {
        pE = pE + 1;
        dwElen = dwElen - 1;
    }
    BIGNUM *pBE = BN_new();
    pBE = BN_bin2bn(pE, dwElen, pBE);

    BIGNUM *pBN = BN_new();
    pBN = BN_bin2bn(pN, dwModulusLen, pBN);

    BIGNUM *pBP = BN_new();
    pBP = BN_bin2bn(pP, dwPrimeLen, pBP);

    BIGNUM *pBQ = BN_new();
    pBQ = BN_bin2bn(pQ, dwPrimeLen, pBQ);

    BIGNUM *pBP1 = BN_new();
    pBP1 = BN_bin2bn(pP1, dwPrimeLen, pBP1);

    BIGNUM *pBQ1 = BN_new();
    pBQ1 = BN_bin2bn(pQ1, dwPrimeLen, pBQ1);

    BIGNUM *pBPQ = BN_new();
    pBPQ = BN_bin2bn(pPQ, dwPrimeLen, pBPQ);

    BIGNUM *pBD = BN_new();
    pBD = BN_bin2bn(pD, dwModulusLen, pBD);

    Rsa.n = pBN;
    Rsa.e = pBE;
    Rsa.p = pBP;
    Rsa.q = pBQ;
    Rsa.dmp1 = pBP1;
    Rsa.dmq1 = pBQ1;
    Rsa.iqmp = pBPQ;
    Rsa.d = pBD;
}

void OpenSSLGenFileHash()
{
    RSA* rsa = RSA_new();
    MSkeyConvertToOpenSSLKey("Test_1024_Key.prv", *rsa);

    const EVP_MD* algrothm = EVP_sha1();
    EVP_MD_CTX mdctx;
    EVP_MD_CTX_init(&mdctx);
    EVP_DigestInit_ex(&mdctx, algrothm, NULL);

    byte file[512] = {0};
    DWORD dwFileSize = sizeof(file);
    ReadBufferFromFile("PublicKey.bin", file, &dwFileSize);

    EVP_DigestUpdate(&mdctx, file, dwFileSize);

    BYTE signValue[128] = {0};
    UINT signLen = 0;
    EVP_DigestFinal_ex(&mdctx, signValue, &signLen);

    EVP_MD_CTX_cleanup(&mdctx);

    RSA_free(rsa);
}

    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3