首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在单独的类中使用Java Native方法时的UnsatisfiedLinkError

在单独的类中使用Java Native方法时的UnsatisfiedLinkError
EN

Stack Overflow用户
提问于 2011-10-18 20:39:47
回答 2查看 2.4K关注 0票数 0

我正在使用Java Native Interface访问我在C++中创建的DLL中的几个本机方法。我可以毫无问题地装入库,但是只有当这些方法位于Java应用程序的主类中时,我才能调用它们。换句话说,只要我声明方法并将loadLibrary命令放在主类中,一切都会完美地工作。

但是,如果我尝试放置loadLibrary命令,并在单独的类中声明本机方法,则会得到以下错误:

代码语言:javascript
复制
Exception in thread "main" java.lang.UnsatisfiedLinkError: sdr_api.SDR_API_Interface.SetDebugFlag_Native(Z)V
at sdr_api.SDR_API_Interface.SetDebugFlag_Native(Native Method)
at sdr_api.SDR_API_Interface.SetDebugFlag(SDR_API_Interface.java:74)
at sdr_api.SDR_API.main(SDR_API.java:183)

我曾尝试查看JNI文档,以检查是否有要求所有本机方法必须在主类中声明,但我找不到任何东西。我希望将这些方法移动到单独的类中,因为我需要在单独的线程中使用它们(我只需要类的一个实例,所以如果需要,可以将它们声明为静态)。

我最好的猜测是,在特定类中声明方法会以某种方式改变它们在DLL中的调用方式,但我不知道是如何改变的。

任何帮助都将不胜感激!

编辑:新增相关代码示例

SDR_API类:

代码语言:javascript
复制
package sdr_api;

public class SDR_API 
{       
    public static void main(String[] args) 
    {

        try
        {
            double Rate = 2e5;
            double TxRxFreq = 5e9;
            double RxGain = 0;
            double TxGain = 0;

            SDR_API_Interface mySDRAPI = new SDR_API_Interface();
            mySDRAPI.SetDebugFlag(true);                              

            mySDRAPI.Setup_BS_Config("addr=192.168.10.2",Rate,Rate,TxRxFreq,TxRxFreq,RxGain,TxGain);
            mySDRAPI.Setup_MT_Config("addr=192.168.20.2",Rate,Rate,TxRxFreq,TxRxFreq,RxGain,TxGain);

         }
         catch(Exception e)
         {
        System.err.println("Exception thrown in main program: "+e);
         }
    }
}

SDR_API_Interface类:

代码语言:javascript
复制
package sdr_api;

public class SDR_API_Interface 
{
    private native boolean Setup_MT_Config_Native(String _IP_Address, 
                                                  double _Rx_Rate, 
                                                  double _Tx_Rate,
                                                  double _Rx_Freq, 
                                                  double _Tx_Freq, 
                                                  double _Rx_Gain, 
                                                  double _Tx_Gain);
    private native boolean Setup_BS_Config_Native(String _IP_Address, 
                                                  double _Rx_Rate, 
                                                  double _Tx_Rate,
                                                  double _Rx_Freq, 
                                                  double _Tx_Freq, 
                                                  double _Rx_Gain, 
                                                  double _Tx_Gain);

    private native void SetDebugFlag_Native(boolean _DebugFlag);

    private native double[] TransmitUL_Native(double[] _TxWaveform);
    private native double[] TransmitDL_Native(double[] _TxWaveform);

    private boolean Debug_Flag = false;

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

    public boolean Setup_MT_Config(String _IP_Address, 
                                    double _Rx_Rate, 
                                    double _Tx_Rate,
                                    double _Rx_Freq, 
                                    double _Tx_Freq, 
                                    double _Rx_Gain, 
                                    double _Tx_Gain)
    {
        return Setup_MT_Config_Native(_IP_Address, 
                                      _Rx_Rate, 
                                      _Tx_Rate,
                                      _Rx_Freq, 
                                      _Tx_Freq, 
                                      _Rx_Gain, 
                                      _Tx_Gain);        
    }

    public boolean Setup_BS_Config(String _IP_Address, 
                                    double _Rx_Rate, 
                                    double _Tx_Rate,
                                    double _Rx_Freq, 
                                    double _Tx_Freq, 
                                    double _Rx_Gain, 
                                    double _Tx_Gain)
    {
        return Setup_BS_Config_Native(_IP_Address, 
                                      _Rx_Rate, 
                                      _Tx_Rate,
                                      _Rx_Freq, 
                                      _Tx_Freq, 
                                      _Rx_Gain, 
                                      _Tx_Gain);         
    }

    public void SetDebugFlag(boolean _DebugFlag)
    {
        Debug_Flag = _DebugFlag;
        SetDebugFlag_Native(Debug_Flag);   
    }

    public boolean GetDebugFlag()
    {
        return Debug_Flag;
    }
}

JNI机器生成的头文件:

代码语言:javascript
复制
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class sdr_api_SDR_API */

#ifndef _Included_sdr_api_SDR_API
#define _Included_sdr_api_SDR_API
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     sdr_api_SDR_API
 * Method:    Setup_MT_Config_Native
 * Signature: (Ljava/lang/String;DDDDDD)Z
 */
JNIEXPORT jboolean JNICALL Java_sdr_1api_SDR_1API_Setup_1MT_1Config_1Native
  (JNIEnv *, jobject, jstring, jdouble, jdouble, jdouble, jdouble, jdouble, jdouble);

/*
 * Class:     sdr_api_SDR_API
 * Method:    Setup_BS_Config_Native
 * Signature: (Ljava/lang/String;DDDDDD)Z
 */
JNIEXPORT jboolean JNICALL Java_sdr_1api_SDR_1API_Setup_1BS_1Config_1Native
  (JNIEnv *, jobject, jstring, jdouble, jdouble, jdouble, jdouble, jdouble, jdouble);

/*
 * Class:     sdr_api_SDR_API
 * Method:    SetDebugFlag_Native
 * Signature: (Z)V
 */
JNIEXPORT void JNICALL Java_sdr_1api_SDR_1API_SetDebugFlag_1Native
  (JNIEnv *, jobject, jboolean);

/*
 * Class:     sdr_api_SDR_API
 * Method:    TransmitUL_Native
 * Signature: ([D)[D
 */
JNIEXPORT jdoubleArray JNICALL Java_sdr_1api_SDR_1API_TransmitUL_1Native
  (JNIEnv *, jobject, jdoubleArray);

/*
 * Class:     sdr_api_SDR_API
 * Method:    TransmitDL_Native
 * Signature: ([D)[D
 */
JNIEXPORT jdoubleArray JNICALL Java_sdr_1api_SDR_1API_TransmitDL_1Native
  (JNIEnv *, jobject, jdoubleArray);

#ifdef __cplusplus
}
#endif
#endif
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-10-19 19:54:02

@Ryan仔细分析头文件,您可以看到本机方法的名称是sdr_api_SDR_API_SetDebugFlag_Native

来自SDR_API_Interface的调用是- sdr_api.SDR_API_Interface.SetDebugFlag_Native

您可能已经使用sdr_api包下的另一个类创建了头文件,即SDR_API。

它应该实际使用接口类创建- sdr_api.SDR_API_Interface.SetDebugFlag_Native

您所需要做的就是编译类SDR_API_Interface,创建头文件,然后创建新的dll来使用它。

您正在使用的dll仍在引用SDR_API类对本机方法的调用。它应该是SDR_API_Interface类。

如果你还有疑问,请告诉我。

票数 5
EN

Stack Overflow用户

发布于 2011-10-18 21:52:49

@Ryan我的问题是,我把带有本机方法的Class放在了另一个包中,把main类放在了另一个包中。

本机方法中的JNICall声明应在C/C++类中指定。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7807340

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档