代码如下:

#include

#include

int main()

{

int a[100];

int i,j,search,count=0;

for(i=0;i<100;i++)

{

a[i]=rand()%100;

}

for(i=0;i<99;i++)

{

for(j=i+1;j<100;j++)

{

int temp;

if(a[i]>a[j])

{

temp=a[i];

a[i]=a[j];

a[j]=temp;

}

}

}

printf("100个100以内的随机数(并且用从小到大排序):\n");

for(i=0;i<100;i++)

{

printf("%d\t",a[i]);

}

printf("请输入要找的数字:\n");

scanf("%d",&search);

for(i=0;i<100;i++)

{

if(search==a[i])

{

printf("found\n");

break;

}

if(search!=a[i])

{

count++;

if(count==100)

printf("not found\n");

}

}

system("PAUSE");

return 0;

}

本程序通俗易懂,希望你能从中有所收获,兄弟,加油啊!

取消

评论

参考:http://www.sxzhongrui.com/cocos2d-x/992.html

参考了Himi的博客:http://www.sxzhongrui.com/android-game/725.html,总结一下在VS2010上面实现如何在cocos2dx项目里利用JNI调用Android的java层代码。

本人用的是cocos2d-x 2.2.2版本,就用最简单的HelloCpp来当做例子。讲例子之前,希望刚接触的朋友还是先去看看Himi的博客:http://www.sxzhongrui.com/android-game/725.html?了解一下JNI大致的一个用法。

在VS2010里面新建TestJNI.h头文件:

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)

#include

#include "platform/android/jni/JniHelper.h"

#endif

#include "cocos2d.h"

USING_NS_CC;

class TestJNI

{

public:

void test1();

void test2();

void test3();

};

其中在写第一行到第四行的时候,本人编译器就自动报了错:说是找不到jni.h头文件,这个错误估计很多人都会遇到,下面说一下解决的办法:

第一步:选中HelloCpp项目,然后:项目->属性->配置属性->VC++目录->包含目录

第二步,在包含目录右边的路径中把JDK安装目录下的D:\jdk1.6\include和D:\jdk1.6\include\win32的路径加到里面去,本人添加的路径是:D:\jdk1.6\include;D:\jdk1.6\include\win32; 。路径之间用“;”分号隔开,还有把上面的路径改成你们机器下面的具体路径就行了。 添加完成之后,点确定按钮,过一会编译就能通过了。然后去cocos2dx的安装目录下的www.sxzhongrui.com32目录下拷贝几个已经编译好的库文件(本人机器上的路径是:E:\develop_sofware\cocos2d-x-2.2.2\cocos2d-x-2.2.2\www.sxzhongrui.com32),我个人就懒得每个去报了错就去这个目录下找,我是直接拷贝www.sxzhongrui.com32这个目录下的所有文件到:HelloCpp工程目录下的www.sxzhongrui.com32里面去(本人目录:E:\develop_sofware\cocos2d-x-2.2.2\cocos2d-x-2.2.2\samples\Cpp\HelloCpp\www.sxzhongrui.com32\www.sxzhongrui.com32)。

不拷贝的话,生成的时候会报诸如:找不到?libcocos2d.lib文件,这些错误。

然后还要配置一下”链接器->输入->附加依赖项",附加依赖项的值增加:如:libExtensions.lib;libcocos2d.lib;libCocosDenshion.lib;opengl32.lib;glew32.lib;libBox2d.lib;libchipmunk.lib;libcurl_imp.lib;pthreadVCE2.lib;websockets.lib;%(AdditionalDependencies

如下图:

这样配置VS基本就应用没什么问题了。(注:每个工程都要这么配置一下!是比较坑爹,我也很郁闷,如果同学们有其他好的方法也请麻烦告诉一下,谢谢!)

测试一下是否可用吧,在VS2010里面再新建一个TestJNI.cpp文件(这里吐槽一下,vs不知道怎么想的,创建头文件的时候不会自动创建相应的CPP文件,可能是本人不会用吧,毕竟没怎么用过VS。Xcode这一点就做的不错。)

#include "TestJNI.h"

void TestJNI::test1(){

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)//判断当前是否为Android平台

// 调用Android里面无参数、无返回值的静态方法

JniMethodInfo methodInfo;

bool isHave = JniHelper::getStaticMethodInfo(methodInfo,"org.cocos2dx.hellocpp.TestJNI","testNoParameNoReturn","()V");

if(!isHave)

{

methodInfo.env->CallStaticVoidMethod(methodInfo.classID,methodInfo.methodID);

}

#endif

}

void TestJNI::test2(){

// 有参数,无返回值

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)//判断当前是否为Android平台

JniMethodInfo methodInfo;

bool isCall = JniHelper::getStaticMethodInfo(methodInfo,"org.cocos2dx.hellocpp.TestJNI","testNoParameButReturn","(I)V");

if(isCall)

{

methodInfo.env->CallStaticVoidMethod(methodInfo.classID,methodInfo.methodID,999);

}

#endif

}

简单说一下大致的意思:在test1()方法中,先判断一下当前环境是否是Android,如果是就执行#if ?#endif块中的代码。定义一个JniMethodInfo类型的对象 methodInfo ,然后把它传到JniHelper::getStaticMethodInfo()方法中。简单说一下JniHelper::getStaticMethodInfo(参数1,参数2,参数3,参数4)这个方法的四个参数: 参数1:JniMethodInfo类型的实例 参数2:需要调用的Android层下面定义了该方法的类的完整路径 参数3:需要调用的方法的名字 参数4:描述参数的参数列表和返回值

前面3个参数都比较好理解,后面第4个参数就要再多说几句:test1()方法中的"()V",代表的意思是:此函数无参数无返回值。再举个例子:如果Android上面写了这么一个函数:public float getIndex(int index); ?参数4就要传入"(I)F",代表调用的方法有一个Int类型的参数,并且会返回一个float类型的数据。具体的类型对照表请看下面:

参数、返回值样式对照表:

调用了JniHelper::getStaticMethodInfo()函数之后,会有个bool返回值,true代表找到了这个方法,false就代表没找着。然后就通过JniMethodInfo类型的对象 methodInfo获得成员变量env,最后通过env调用CallStaticVoidMethod函数来具体调用Android层上面对应的那个方法。(是不是感觉有点像java的反射?呵呵)。

好,VS上面的代码就写到这里,再看看Android工程里面是怎么弄的:

第一步,先导入HelloCpp工程(去cocos2d目录下面去找,本人的路径是:E:\develop_sofware\cocos2d-x-2.2.2\cocos2d-x-2.2.2\samples\Cpp\HelloCpp\proj.android);

第二步,点开工程目录下的jni目录,如下图:

然后打开www.sxzhongrui.com文件,在里面把我们刚才在VS上面新建的那个TestJNI.cpp文件路径也弄进去(注:经常有的时候在VS或者Xcode上面新加了cpp文件,忘记加到这里去,编译的时候老是通过不过,这个地方要小心点!),具体如下:

第三步,编写www.sxzhongrui.com文件(这个名字随便起,不过要对应VS上面调用的类名),代码如下:

然后运行,效果如下:

这里注明一下:Android工程的sdk版本必须是2.3以上才能运行正常。

关于多参数传递的问题:

举例:

java代码中有:

public static void showThree(bool b, int i)

那么对应的C++调用代码为:

void TestJNI::showThree(bool b, int i){

#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)//判断当前是否为Android平台

JniMethodInfo jmi;

bool ishave = JniHelper::getStaticMethodInfo(jmi,Package_Utils_Path,"showThree","(ZI)V");

if(ishave)

{

jboolean isShow = b;

jint p = i;

jmi.env->CallStaticVoidMethod(jmi.classID,jmi.methodID,isShow,p);

}

#endif

}

上面代码中的"(ZI)V",表示:该函数包含两个参数,分别是:java中的boolean类型和int类型,返回值为void。

总结:获取多参数函数的时候,参数类型之间不用写分隔符。

jpcap是一个java实现的抓包库,非常易于使用,对于简单的网络结构来说是菜鸟的福音,他在windows中其底层调用的是winpcap进行的抓包,但是它的功能有限,仅实现了对普通的四层网络的数据包的解析,现在因为项目需要需要实现对iptv数据包的解析,思来想去觉得只有扩展jpcap的功能最方便实现,于是用vs2010重新编译了jpcap 的dll,编译只是第一步,要实现扩展首先要实现对dll的调试运行。在网上搜索一番找到了一个解决方案,比较好用,记在这里。

java开发环境:Eclipse+java1.7

C开发环境:VS2010,直接打开jpcap-0.7\src\c\win32\win32.sln设置工程属性将java的jni.h所在的目录加进C++包含路径即可成功编译,对于我这种菜鸟来说真的是太方便了(wireshark的编译就相当麻烦)。

调试方法:

在Eclipse中设置一个断点,调试,程序会停在断点处。

在vs中jpcap解析数据包是在JpcapCaptor.c中的get_packet中实现的,所以在这个函数中也设置一个断点,然后选择菜单->调试->附加到进程,弹出如下图所示的对话框。

选择红色方框圈住的javaw.exe的进程,确定,vs进入调试模式。再在Eclipse继续调试,vs中就停在断点出啦,哈哈。