【改进】使用NDK生成native C/C++的可执行程序

本文介绍如何使用Android NDK生成C/C++可执行程序,并详细解释如何更改可执行文件名称以便能在APK安装过程中正确复制到目标目录。此外,还提供了执行该程序所需的Java代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:http://blog.youkuaiyun.com/nicebooks/article/details/6601005

原作者未说明一个问题 “.可执行文件的名字必须是lib*.so. ” ,本文中回答了如何让产生的可执行文件的文件名改变


众所周知, NDK可以生成lib,让java程序通过jni来调用,其实,NDK也可以生成C/C++的可执行程序.不过这个程序要被执行的话还有要求.   

1.可执行文件的名字必须是lib*.so. 否则apk安装时不会安装上去,因为目前apk的安装只支持安装lib文件,即lib*.so文件,如果不是此文件格式的,安装时不会拷到lib目录里.也可以考虑把可执行文件放assets里,java程序运行后把它拷贝到其它目录或系统目录. 

2.这个文件的执行必须由java程序通过Runtime.getRuntime().exec()来执行.

下面来看看代码.

test.c 可以将此文件放在android项目的jni目录里,需要自己创建jni目录,与res,src等目录同级.

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

 

int main(int argc, char* argv[])

{

    FILE *fp1;

    char ch;

    sleep(10);  // sleep 10second

    if ((fp1 =fopen("textc.txt", "w")) == NULL)

    {

       printf("open file failed");

        exit(0);

    }

 

    fprintf(fp1, "teststring1");

    fclose(fp1);

    return 0;

}

再看看makefile文件.与test.c在同一目录

Android.mk

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

 

LOCAL_SRC_FILES:= test.c

 

LOCAL_MODULE:= test

 

LOCAL_FORCE_STATIC_EXECUTABLE := true

 

LOCAL_STATIC_LIBRARIES := libc

 

LOCAL_MODULE_PATH :=$(TARGET_OUT_OPTIONAL_EXECUTABLES)

LOCAL_MODULE_TAGS := debug

LOCAL_MODULE_FILENAME :="libtest.so"  #改文件名

include $(BUILD_EXECUTABLE)

注意上面的makefile,与生成lib的差别就是最后以行include $(BUILD_EXECUTABLE),这个是生成可执行文件的关键.

 

android项目代码,android项目是一个简单的例子,其中只有一个textview,将其id设为textView01.只有一个Activity:

package com.nicebooks.naviteexec;

 

import java.io.DataInputStream;

import java.io.DataOutputStream;

import android.app.Activity;

import android.os.Bundle;

import android.widget.TextView;

 

public class MyActivity extends Activity {

    TextView mTextView01;

 

    @Override

    public void onCreate(BundlesavedInstanceState) {

       super.onCreate(savedInstanceState);

       setContentView(R.layout.main);

        mTextView01 =(TextView) findViewById(R.id.textView01);

        String path ="/data/data/" + getPackageName();

        String cmd1 =path + "/lib/libtest.so";

        String cmd2 =path + "/test";

        String cmd3 ="chmod 777 " + cmd2;

        String cmd4 ="dd if=" + cmd1 + " of=" + cmd2;

       RootCommand(cmd4);              //拷贝lib/libtest.so到上一层目录,同时命名为test.

       RootCommand(cmd3);              //改变test的属性,让其变为可执行

       RootCommand(cmd2);              //执行test程序.

    }

 

    public booleanRootCommand(String command) {

        Process process= null;

        try {

           process = Runtime.getRuntime().exec("sh");  //获得shell.

           DataInputStream inputStream = new DataInputStream(process.getInputStream());

           DataOutputStream outputStream = newDataOutputStream(process.getOutputStream());

           outputStream.writeBytes(cd /data/data/" + getPackageName() +"\n");  //保证在command在自己的数据目录里执行,才有权限写文件到当前目录

 

           outputStream.writeBytes(command + " &\n"); //让程序在后台运行,前台马上返回

           outputStream.writeBytes("exit\n");

           outputStream.flush();

           process.waitFor();

           

           byte[] buffer = new byte[inputStream.available()];

           inputStream.read(buffer);

           String s = new String(buffer);

           mTextView01.setText("CMD Result:\n" + s);

        } catch(Exception e) {

           mTextView01.setText("Exception:"+ e.getMessage());

           return false;

        }

        return true;

    }

}

看看layout文件

main.xml

<?xml version="1.0"encoding="utf-8"?>

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"

   android:orientation="vertical"

    android:layout_width="fill_parent"

   android:layout_height="fill_parent"

    >

<TextView 

   android:id="@+id/textView01"

   android:layout_width="fill_parent"

   android:layout_height="wrap_content"

   android:text="@string/hello"

    />

</LinearLayout>

 

下面开始build, 关于cygwin和NDK的环境这篇文章就不再讲,大家可以去google一下.

1.进入cygwin,cd到android项目的jni的路径,输入ndk-build,如果不出错,将在android项目里生成一个libs目录.libs目录还生成一个armeabi.在armeabi目录里会有一个test文件.

2.我们要将test文件改名成libtest.so.

3.然后在eclipse里clean/build.

4.将程序在手机上运行.可以看到 程序自己的数据目录下生成一个textc.txt文件.

而且即使java程序退出了,此test程序仍在执行,因为我用sleep和后台执行方式来执行的.test已经是一个独立的进程在android系统里运行了.

 

如果手机是破解的,有root权限的,可以将process =Runtime.getRuntime().exec("su");来替换上面同一行程序.这样你可以随意写文件到root能操作的目录,也可以执行其它root才能执行的命令.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值