方兆国 发表于 2013-07-19 11:37

JavaNative 使用C多线程库的问题

Java类文件package com.fangzhaoguo.primefinder;

public class NativeConcurrentPrimeFinder {

        static {
                System.loadLibrary("libJavaNative_ConcurrentPrimeFinder");
        }

        public NativeConcurrentPrimeFinder() {
        }

        public native boolean isPrime(final long number);

        public native int countPrime(final long number);

        public native int countPrime(final long lower, final long upper);
}
javah后的C头文件,并且经过我的修改,加入了自定义的变量、数据结构以及函数/* DO NOT EDIT THIS FILE - it is machine generated */
#include "jni.h"
#include <pthread.h>
#include <stdio.h>
#include <malloc.h>
#include <math.h>
/* Header for class com_fangzhaoguo_primefinder_NativeConcurrentPrimeFinder */
jint total = 0;

typedef struct {
        JNIEnv *env;
        jobject obj;
        jlong lower;
        jlong upper;
} Message;

#ifndef _Included_com_fangzhaoguo_primefinder_NativeConcurrentPrimeFinder
#define _Included_com_fangzhaoguo_primefinder_NativeConcurrentPrimeFinder
#ifdef __cplusplus
extern "C" {
#endif
        /*
       * Class:   com_fangzhaoguo_primefinder_NativeConcurrentPrimeFinder
       * Method:    isPrime
       * Signature: (J)Z
       */
        JNIEXPORT jboolean JNICALL Java_com_fangzhaoguo_primefinder_NativeConcurrentPrimeFinder_isPrime(
                        JNIEnv *, jobject, jlong);

        /*
       * Class:   com_fangzhaoguo_primefinder_NativeConcurrentPrimeFinder
       * Method:    countPrime
       * Signature: (J)I
       */
        JNIEXPORT jint JNICALL Java_com_fangzhaoguo_primefinder_NativeConcurrentPrimeFinder_countPrime__J(
                        JNIEnv *, jobject, jlong);

        /*
       * Class:   com_fangzhaoguo_primefinder_NativeConcurrentPrimeFinder
       * Method:    countPrime
       * Signature: (JJ)I
       */
        JNIEXPORT jint JNICALL Java_com_fangzhaoguo_primefinder_NativeConcurrentPrimeFinder_countPrime__JJ(
                        JNIEnv *, jobject, jlong, jlong);

        void *countPrimeInRange(void* mess);

#ifdef __cplusplus
}
#endif
#endif
Mingw编译的C文件 ,使用了pthread头文件,并且在链接时使用了pthread,编译正常
线程调用时通过message来传递JavaNative特有的参数
/*
* com_fangzhaoguo_primefinder_NativeConcurrentPrimeFinder.c
*
*Created on: 2013年7月18日
*      Author: root
*/

#include "com_fangzhaoguo_primefinder_NativeConcurrentPrimeFinder.h"

JNIEXPORT jboolean JNICALL Java_com_fangzhaoguo_primefinder_NativePrimeFinder_isPrime(
                JNIEnv *env, jobject obj, jlong number) {
        jlong i = 0;
        if (1 >= number) {
                return 0;
        }
        for (i = 2; i <= sqrt(number); i++) {
                if (0 == number % i) {
                        return 0;
                }
        }
        return 1;
}

void *countPrimeInRange(void* mess) {
        jlong i = 0;
        Message* message = (Message*) mess;
        for (i = message->lower; i < message->upper; i++) {
                if (Java_com_fangzhaoguo_primefinder_NativePrimeFinder_isPrime(
                                message->env, message->obj, i)) {
                        total++;
                }
        }
        return NULL;
}

JNIEXPORT jint JNICALL Java_com_fangzhaoguo_primefinder_NativePrimeFinder_countPrime__J(
                JNIEnv *env, jobject obj, jlong number) {
        pthread_t thread;
        Message* message = (Message*) malloc(sizeof(Message));
        message->env = env;
        message->obj = obj;
        jlong start = 0, end = 0;
        jlong range = number / 4;
        jint i = 0;
        for (i = 0; i < 4; i++) {
                start = 0 + range * i;
                if (i < 3) {
                        end = start + range;
                } else {
                        end = number;
                }
                message->lower = start;
                message->upper = end;
                pthread_create(&thread, NULL, countPrimeInRange, (void*) message);
        }
        return total;
}

JNIEXPORT jint JNICALL Java_com_fangzhaoguo_primefinder_NativePrimeFinder_countPrime__JJ(
                JNIEnv *env, jobject obj, jlong lower, jlong upper) {
        jlong i = 0;
        for (i = lower; i < upper; i++) {
                if (Java_com_fangzhaoguo_primefinder_NativePrimeFinder_isPrime(env, obj,
                                i)) {
                        total++;
                }
        }
        return total;
}
但是现在的问题是在java中运行时报错,不管使用C写还是加载boost类的C++写,都报相同的错误。有不使用C/C++多线程的例子,可以正常使用
以下是报错内容Exception in thread "main" java.lang.UnsatisfiedLinkError: com.fangzhaoguo.primefinder.NativeConcurrentPrimeFinder.countPrime(J)I
        at com.fangzhaoguo.primefinder.NativeConcurrentPrimeFinder.countPrime(Native Method)
        at com.fangzhaoguo.primefinder.Main.timeAndCompute(Main.java:58)
        at com.fangzhaoguo.primefinder.Main.main(Main.java:6)

weishuo1999 发表于 2013-07-20 23:58

看看是不是编译的原因,strings看一下你的函数名的符号有没有多个@符号,如果有的话,改一下编译参数

方兆国 发表于 2013-07-21 11:59

使用nm看吗?有下划线数量的变化,没有发现@
不过boost版的问题多些
页: [1]
查看完整版本: JavaNative 使用C多线程库的问题