简体   繁体   English

NDK对{extern“ C”函数}的引用未定义?

[英]NDK undefined reference to {extern “C” function}?

I try to develop an Android app. 我尝试开发一个Android应用程序。 I already managed to implement a rather small c++ function using NDK. 我已经设法使用NDK实现一个相当小的c ++函数。 But now I want to use a pretty large c++ library which I found on Google Docs. 但是现在我想使用一个很大的c ++库,该库是我在Google文档中找到的。 When I now try to build it with ndk-build tool, I get this error in cygwin console: 现在,当我尝试使用ndk-build工具进行构建时,在cygwin控制台中出现此错误:

Compile++ thumb  : ndkfoo <= subspace.cpp
Compile++ thumb  : ndkfoo <= classifier.cpp
Compile++ thumb  : ndkfoo <= eigen.cpp
Compile++ thumb  : ndkfoo <= image.cpp
Compile++ thumb  : ndkfoo <= imageio.cpp
Compile++ thumb  : ndkfoo <= local.cpp
Compile++ thumb  : ndkfoo <= matrix.cpp
Compile++ thumb  : ndkfoo <= sample.cpp
SharedLibrary  : libndkfoo.so
./obj/local/armeabi/objs/ndkfoo/eigen.o: In function `LibSubspace::geneigen(doub
le*, double*, int, double*, int, bool)':
U:\workspace\test/jni/eigen.cpp:91: undefined reference to `ilaenv_'
U:\workspace\test/jni/eigen.cpp:96: undefined reference to `dsygv_'
U:\workspace\test/jni/eigen.cpp:128: undefined reference to `dggev_'
./obj/local/armeabi/objs/ndkfoo/eigen.o: In function `LibSubspace::eigen(double*
, double*, double*, int, bool)':
U:\workspace\test/jni/eigen.cpp:55: undefined reference to `ilaenv_'
U:\workspace\test/jni/eigen.cpp:58: undefined reference to `dsyev_'
collect2: ld returned 1 exit status
make: *** [obj/local/armeabi/libndkfoo.so] Error 1

The Code of this function is as follow: 该函数的代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <float.h>
#include <assert.h>
#include <string.h>

#include "eigen.h"

extern "C" int ilaenv_(int *ispec, const char *name__, const char *opts,
    int *n1, int *n2, int *n3, int *n4, int name_len, int opts_len);

extern "C" int dsyev_(const char *jobz, const char *uplo, int *n, double *a,
    int *lda, double *w, double *work, int *lwork, 
    int *info);

extern "C" int dsygv_(int *itype, const char *jobz, const char *uplo, int *
    n, double *a, int *lda, double *b, int *ldb, 
    double *w, double *work, int *lwork, int *info);

extern "C" int dggev_(const char *jobvl, const char *jobvr, int *n, double *
    a, int *lda, double *b, int *ldb, double *alphar, 
    double *alphai, double *beta, double *vl, int *ldvl, 
    double *vr, int *ldvr, double *work, int *lwork, 
    int *info);

namespace LibSubspace {

int eigen(double* A, double* V, double* E, int n, bool verbose) {
    int info;
    int ispec = 1;
    int lwork;

    lwork = (ilaenv_(&ispec,"DSYEV","U",&n,&n,&n,&n,5,1)+2)*n;
    double *work = (double *)malloc(lwork*sizeof(double));
    memcpy(V,A,n*n*sizeof(double));
    dsyev_("V","U",&n,V,&n,E,work,&lwork,&info);
    free(work);

    //check the return value
    if(info!=0) {
        if(verbose) {
            printf("Error computing eigenvectors: ");
            if(info>0) {
                printf("Algorithm failed to converge\n");
            } else if(info<0) {
                printf("Illegal argument\n");
            } else {
                printf("Unknown error\n");
            }
        }
        return 0;
    }

    return 1;
}


int geneigen(double *A, double *B, int n, double *W, int algorithm,
             bool verbose) {
    //getting the optimal lwork
    int ispec = 1;
    int lwork;
    int info;

    switch(algorithm) {

        case EIGEN_CHOL: 
        {
            //computing eigenvectors
            lwork = (ilaenv_(&ispec,"DSYGV","U",&n,&n,&n,&n,5,1)+2)*n;
            double *work = (double *)malloc(lwork*sizeof(double));
            int problemType = 1;
            char job = 'V';
            char uplo = 'U';
            dsygv_(&problemType,&job,&uplo,&n,A,&n,B,&n,W,work,&lwork,&info);

            free(work);

            //check the return value
            if(info!=0) {
                if(verbose) {
                    printf("Error computing eigenvectors: ");
                    if(info>n) {
                        printf("Matrix B is not positive definite\n");
                    } else if(info<=n) {
                        printf("The problem failed to converge\n");
                    } else if(info<0) {
                        printf("Illegal argument\n");
                    } else {
                        printf("Unknown error\n");
                    }
                }
                return 0;
            }
        }
        break;

        case EIGEN_QZ:
        {
            //more general algorithm
            double *alphar = (double *)malloc(n*sizeof(double));
            double *alphai = (double *)malloc(n*sizeof(double));
            double *beta = (double *)malloc(n*sizeof(double));
            double *VR = (double *)malloc(n*n*sizeof(double));
            lwork = 8*n;
            double *work = (double *)malloc(lwork*sizeof(double));
            dggev_("N","V",&n,A,&n,B,&n,alphar,alphai,beta,
                                   NULL,&n,VR,&n,work,&lwork,&info);
            //eigenvalues
            for(long i=0;i<n;i++) {
                if(beta[i]!=0) {
                    W[i] = alphar[i]/beta[i];
                } else W[i] = 0;
            }
            //eigenvectors
            for(long i=0;i<n;i++) {
                for(long j=0;j<n;j++) {
                    A[i*n+j] = VR[i*n+j];
                }
            }
            free(alphar);
            free(alphai);
            free(beta);
            free(VR);   
            free(work);

            if(info!=0) {
                printf("Error computing eigenvectors: ");
                if(info<0) {
                    printf("Illegal argument\n");
                } else if(info<=n) {
                    printf("QZ iteration failed\n");
                } else {
                    printf("Unknown error\n");
                }
                return 0;
            }
        }
        break;

    }

    return 1;
}

} //namespace

Unfortunatly I absolutly DONT understand why these errors occur. 不幸的是,我绝对不理解为什么会发生这些错误。 I am not much familiar with C++, thats why I wanted to use NDK in the hope of not having to change anything of the existing library. 我对C ++不太熟悉,这就是为什么我想要使用NDK而不希望更改现有库的任何内容的原因。

Google tells me that these functions are from the runtime of Fortran-to-C compiler. Google告诉我,这些功能来自Fortran-to-C编译器的运行时。 So you need to either link against a library called libf2c , or find the sources and make them a part of the NDK project too. 因此,您需要链接到名为libf2c的库,或者查找源并将它们也纳入NDK项目。 The latter sounds like a more promising approach - I don't think a ready made NDK build exists. 后者听起来是一种更有希望的方法-我认为不存在现成的NDK构建。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM