c语言 如何通过使用windows系统调用来计算一段程序的运行时间?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了c语言 如何通过使用windows系统调用来计算一段程序的运行时间?相关的知识,希望对你有一定的参考价值。

#include "stdio.h"
#include "stdlib.h"
#include "time.h"

int main( void )


clock_t start = clock();

//此处写你的代码

clock_t finish = clock();

double duration = (double)(finish - start) / CLOCKS_PER_SEC;
printf( "%f seconds\n", duration );//这里就是时间了

return 0;


还有问题欢迎继续hi我追问

我想使计时精度高一些,使用timeGettime,如何写代码?

追答

我没用过gettime但是看了一下,他们精度都是毫秒级, clock精度不会比gettime低, 而且gettime 看了一下别人的代码, 计算方法还比较复杂... 我的简化版编译器很多库没有,所以现在不能给你现成的代码,我不建议用那个函数

参考技术A 这个需要c语言函数库里的函数 建议百度一下c语言的计时函数即可

JNI的基本使用一

介绍

       JNI即Java Native Interface的简称,java本地方法接口,通过JNI Java可以和C相互调用。Java语言也是通过JNI接口来调用系统的功能,只不过JNI的实现部分在JDK中,这样可以增加Java的功能。同样用户程序也可以通过实现JNI接口来调用本地方法。如: 如: windows和linux上Java程序需要调用外设驱动,就需要使用JNI;android上NDK也是通过JNI进行调用。本文主要讲解在windows上java通过jni调用本地方法,测试效果和在android上通过java调用so一样(JNI的规则一致的),为了方便点采用windows来实践。

准备工作:

  1. vs2015

  2. IntelliJ

    本次通过vs2015编写dll,然后通过java进行调用。

数据类型

基本数据类型

Java类型JNI类型说明
booleanjbooleantypedef unsigned char jboolean;
bytejbytetypedef signed char jbyte;
charjchartypedef unsigned short jchar;
shortjshorttypedef short jshort;
intjinttypedef long jint;
longjlongtypedef __int64 jlong;
floatjfloattypedef float jfloat;
doublejdoubletypedef double jdouble;
voidvoidvoid

从上可以看出jni中的基本类型,都是由其他类型定义而来

引用类型

  • jobject

    • jclass (java.lang.Class objects)

    • jstring (java.lang.String objects)

    • jarray (arrays)

      • jobjectArray (object arrays)

      • jbooleanArray (boolean arrays)

      • jbyteArray (byte arrays)

      • jcharArray (char arrays)

      • jshortArray (short arrays)

      • jintArray (int arrays)

      • jlongArray (long arrays)

      • jfloatArray (float arrays)

      • jdoubleArray (double arrays)

    • jthrowable (java.lang.Throwable objects)

签名

签名Java类型
Zboolean
Bbyte
Cchar
Sshort
Iint
Jlong
Ffloat
Ddouble
L fully-class;  fully-class
[typetype[]

例子:

void test(int arg1, byte arg2, char arg3, String []arg4);

方法签名: (IBC[Ljava/lang/String;)V

类属性映射

JavaJni
MethodjmethodID
FieldjfieldID

Java调用JNI准备

  1. 需要调用使用jni的java文件需要静态加载动态库

static 
        System.loadLibrary("JNIDll");

2.声明native方法,native方法与c层实现的代码一一对映

 public native void javaCallNative();
    public native void javaCallNative1(int arg);
    public native void javaCallNative2(long arg);
    public native void javaCallNative3(float arg);
    public native void javaCallNative4(byte[] arg);
    public native void javaCallNative5(String arg);
    /**
     * 通过该接口c层回调java接口
     */
    public native void nativeCallJavaTest();

Java测试代码如下:

package com.stx.jni;

import java.io.File;

public class JNITest 

    static 
        System.loadLibrary("JNIDll");
    

    public static void main(String[] args) 
        System.out.println("==================");
        File file = new File("");
        System.out.println("curDir " + file.getAbsolutePath());
        JNITest jniTest = new JNITest();
        jniTest.javaCallNative();

        jniTest.javaCallNative1(1);
        jniTest.javaCallNative2(2);
        jniTest.javaCallNative3(3.0f);
        byte[] byteTest = new byte[]1, 2, 3, 4, 5, 6;
        jniTest.javaCallNative4(byteTest);
        String strTest = "Hello World";
        jniTest.javaCallNative5(strTest);
        jniTest.nativeCallJavaTest();
    

    public native void javaCallNative();

    public native void javaCallNative1(int arg);
    public native void javaCallNative2(long arg);
    public native void javaCallNative3(float arg);
    public native void javaCallNative4(byte[] arg);
    public native void javaCallNative5(String arg);
    /**
     * 通过该接口c层回调java接口
     */
    public native void nativeCallJavaTest();


    /**
     * 提供给JNI调用
     * @param arg1
     * @param arg2
     * @param arg3
     */
    public void test(int arg1, byte[] arg2, String arg3)
        System.out.println("this is java test print...");
        System.out.println("arg1: " + arg1);
        System.out.println("================arg2 begin=============");
        for (byte b : arg2)
            System.out.println(""+b);
        
        System.out.println("================arg2 end=============");
        System.out.println("arg3: " + arg3);
    
    

C代码

工程准备

  1. 新建一个vs2015工程,选择dll

    文件->新建项目

点击确定,然后点击下一步,选择建dll工程

  1. 点击完成,工程就建好了。

  2. 将jni.h和jni_md.h拷贝到工程目录中

    C:\\Program Files\\Java\\jdk1.8.0_231\\include\\jni.h

    C:\\Program Files\\Java\\jdk1.8.0_231\\include\\win32\\jni_md.h

    并将其添加到工程中

  3. 新建jni实现文件 JNIDll.h和JNIDll.cpp

    本次实现为静态注册的方式,对静态注册说明一下, jni中的函数如何和java中的函数进行绑定
    通用格式如下, 如果包名为a.b.c, java文件名为d, 函数名为f,那么jni中的对应的函数名为:Java_a_b_c_d_f
    以测试工程包为例:
     

    javajni
    javaCallNative
    Java_com_stx_jni_JNITest_javaCallNative

     
  4. 代码如下:

    头文件

    #pragma once
    #include	"jni.h"
    
    #ifndef _Included_JNIDLL
    #define _Included_JNIDLL
    #ifdef __cplusplus
    extern "C" 
    #endif
    
    
    	JNIEXPORT void JNICALL Java_com_stx_jni_JNITest_javaCallNative
    	(JNIEnv *, jobject);
    	JNIEXPORT int JNICALL Java_com_stx_jni_JNITest_javaCallNative1
    	(JNIEnv *, jobject, jint);
    	JNIEXPORT int JNICALL Java_com_stx_jni_JNITest_javaCallNative2
    	(JNIEnv *, jobject, jlong);
    	JNIEXPORT int JNICALL Java_com_stx_jni_JNITest_javaCallNative3
    	(JNIEnv *, jobject, jfloat);
    	JNIEXPORT int JNICALL Java_com_stx_jni_JNITest_javaCallNative4
    	(JNIEnv *, jobject, jbyteArray);
    	JNIEXPORT int JNICALL Java_com_stx_jni_JNITest_javaCallNative5
    	(JNIEnv *, jobject, jstring);
    
    	JNIEXPORT void JNICALL Java_com_stx_jni_JNITest_nativeCallJavaTest
    	(JNIEnv *, jobject);
    
    
    	char* jstringtochar(JNIEnv *env, jstring jsStr);
    	jstring chartojstring(JNIEnv* env, char* csStr);
    
    #ifdef __cplusplus
    
    #endif
    #endif
    
    
    


    c定义

    // JNIDll.cpp : 定义 DLL 应用程序的导出函数。
    //
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include "jni.h"
    #include "JNIDll.h"
    
    
    
    JNIEXPORT void JNICALL Java_com_stx_jni_JNITest_javaCallNative
    (JNIEnv * env, jobject jObj) 
    	printf("Java_com_stx_jni_JNITest_javaCallNative---->\\n");
    
    
    JNIEXPORT int JNICALL Java_com_stx_jni_JNITest_javaCallNative1
    (JNIEnv * env, jobject jObj, jint arg) 
    	printf("Java_com_stx_jni_JNITest_javaCallNative1---->, arg: %d\\n", arg);
    	return 0;
    
    
    
    JNIEXPORT int JNICALL Java_com_stx_jni_JNITest_javaCallNative2
    (JNIEnv *env, jobject jObj, jlong arg) 
    	printf("Java_com_stx_jni_JNITest_javaCallNative2---->, arg: %d\\n", arg);
    	return 0;
    
    
    JNIEXPORT int JNICALL Java_com_stx_jni_JNITest_javaCallNative3
    (JNIEnv *env, jobject jObj, jfloat arg)
    	printf("Java_com_stx_jni_JNITest_javaCallNativ3---->, arg: %f\\n", arg);
    	return 0;
    
    
    
    JNIEXPORT int JNICALL Java_com_stx_jni_JNITest_javaCallNative4
    (JNIEnv *env, jobject jObj, jbyteArray arg) 
    
    	printf("Java_com_stx_jni_JNITest_javaCallNative4---->\\n");
    	int len = env->GetArrayLength(arg);
    	jbyte * pArray = env->GetByteArrayElements(arg, JNI_FALSE);
    	for (int i = 0; i < len; i++) 
    		printf("%d\\n", pArray[i]);
    	
    	env->ReleaseByteArrayElements(arg, pArray, JNI_FALSE);
    	return 0;
    
    
    
    JNIEXPORT int JNICALL Java_com_stx_jni_JNITest_javaCallNative5
    (JNIEnv *env, jobject jObj, jstring arg) 
    	printf("Java_com_stx_jni_JNITest_javaCallNative5---->\\n");
    	const char* csArgs = env->GetStringUTFChars(arg, false);
    	printf("csArgs: %s\\n", csArgs);
    	env->ReleaseStringUTFChars(arg, csArgs);
    	return 0;
    
    
    
    
    JNIEXPORT void JNICALL Java_com_stx_jni_JNITest_nativeCallJavaTest
    (JNIEnv *env, jobject jObj) 
    	printf("Java_com_stx_jni_JNITest_nativeCallJavaTest---->\\n");
    	jclass clazz = env->FindClass("com/stx/jni/JNITest");
    	if (clazz == NULL)
    		clazz = env->GetObjectClass(jObj);
    
    	if (clazz != NULL) 
    		jmethodID method = env->GetMethodID(clazz, "test", "(I[BLjava/lang/String;)V");
    		if(method != NULL)
    			int arg1 = 10;
    			jbyte* pByte = new jbyte[6];
    			for (int i = 0; i < 6; i++) 
    				pByte[i] = i;
    			
    			jbyteArray arg2 = env->NewByteArray(6);
    			env->SetByteArrayRegion(arg2, 0, 6, pByte);
    
    			char* pCsStr = "C++ Char";
    			jstring arg3 = chartojstring(env, pCsStr);
    			env->CallVoidMethod(jObj, method, arg1, arg2, arg3);
    		
    		else 
    			printf("find method test faild...");
    		
    	
    	else 
    		printf("find class faild...");
    	
    
    
    
    char* jstringtochar(JNIEnv *env, jstring jsStr) 
    	char* rtn = NULL;
    	jclass clsstring = env->FindClass("java/lang/String");
    	jstring strencode = env->NewStringUTF("utf-8");
    	jmethodID mid = env->GetMethodID(clsstring, "getBytes", "(Ljava/lang/String;)[B");
    	jbyteArray barr = (jbyteArray)env->CallObjectMethod(jsStr, mid, strencode);
    	jsize alen = env->GetArrayLength(barr);
    	jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
    	if (alen > 0)
    		rtn = (char*)malloc(alen + 1);
    		memcpy(rtn, ba, alen);
    		rtn[alen] = 0;
    	
    	env->ReleaseByteArrayElements(barr, ba, 0);
    	return rtn;
    
    
    jstring chartojstring(JNIEnv* env, char* csStr) 
    	jclass strClass = env->FindClass("Ljava/lang/String;");
    	jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;)V");
    	jbyteArray bytes = env->NewByteArray(strlen(csStr));
    	env->SetByteArrayRegion(bytes, 0, strlen(csStr), (jbyte*)csStr);
    	jstring encoding = env->NewStringUTF("utf-8");
    	return (jstring)env->NewObject(strClass, ctorID, bytes, encoding);
    
    
    


    以上代码都可以编译运行通过。

         win32源码下载

 

 

以上是关于c语言 如何通过使用windows系统调用来计算一段程序的运行时间?的主要内容,如果未能解决你的问题,请参考以下文章

第一个问题,也是主要问题,c 语言的FILE结构是怎么实现的。经过网上查了一下说是通过调用系统AP

如何实现C语言的多处理器并行计算

JNI的基本使用一

JNI的基本使用一

JNI的基本使用一

如何在C语言中调用cmd命令?