Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/389.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在单独的类中使用Java本机方法时出现不满意的LinkError_Java_Java Native Interface - Fatal编程技术网

在单独的类中使用Java本机方法时出现不满意的LinkError

在单独的类中使用Java本机方法时出现不满意的LinkError,java,java-native-interface,Java,Java Native Interface,我使用java本机接口访问C++中创建的DLL中的几种本地方法。我可以毫无问题地加载库,但我只能在方法位于Java应用程序的主类中时调用它们。换句话说,只要我声明方法并将loadLibrary命令放在主类中,一切都可以完美地工作 但是,如果尝试放置loadLibrary命令,并在单独的类中声明本机方法,则会出现以下错误: Exception in thread "main" java.lang.UnsatisfiedLinkError: sdr_api.SDR_API_Interface.Set

我使用java本机接口访问C++中创建的DLL中的几种本地方法。我可以毫无问题地加载库,但我只能在方法位于Java应用程序的主类中时调用它们。换句话说,只要我声明方法并将loadLibrary命令放在主类中,一切都可以完美地工作

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

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类:

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_接口类:

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计算机生成的头文件:

/* 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
/*不要编辑此文件-它是机器生成的*/
#包括
/*类sdr\u api\u sdr\u api的标头*/
#如果NDEF包括sdr api sdr api
#定义包含的sdr api sdr api
#ifdef_uucplusplus
外部“C”{
#恩迪夫
/*
*类别:sdr\U api\U sdr\U api
*方法:设置\u MT\u配置\u本机
*签名:(Ljava/lang/String;DDDDDD)Z
*/
JNIEXPORT jboolean JNICALL Java\u sdr\u 1api\u sdr\u 1api\u设置\u 1MT\u 1配置\u 1本机
(JNIEnv*,jobject,jstring,jdouble,jdouble,jdouble,jdouble,jdouble,jdouble);
/*
*类别:sdr\U api\U sdr\U api
*方法:设置\u BS\u配置\u本机
*签名:(Ljava/lang/String;DDDDDD)Z
*/
JNIEXPORT jboolean JNICALL Java_sdr_1api_sdr_1api_设置_1BS_1配置_1本机
(JNIEnv*,jobject,jstring,jdouble,jdouble,jdouble,jdouble,jdouble,jdouble);
/*
*类别:sdr\U api\U sdr\U api
*方法:SetDebugFlag_Native
*签字:(Z)五
*/
JNIEXPORT void JNICALL Java_sdr_1api_sdr_1api_SetDebugFlag_1Native
(JNIEnv*,jobject,jboolean);
/*
*类别:sdr\U api\U sdr\U api
*方法:TransmitUL_Native
*签字:(D)[D]
*/
JNIEXPORT jdoubleArray JNICALL Java_sdr_1api_sdr_1api_TransmitUL_1本机
(JNIEnv*,jobject,jdoubleArray);
/*
*类别:sdr\U api\U sdr\U api
*方法:TransmitDL_Native
*签字:(D)[D]
*/
JNIEXPORT jdoubleArray JNICALL Java_sdr_1api_sdr_1api_TransmitDL_1本机
(JNIEnv*,jobject,jdoubleArray);
#ifdef_uucplusplus
}
#恩迪夫
#恩迪夫
@Ryan 我的问题是,我将带有本机方法的类放在另一个包中,而将主类放在另一个包中

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

@Ryan 我的问题是,我将带有本机方法的类放在另一个包中,而将主类放在另一个包中

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

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

来自SDR_API_接口的调用为- sdr_api.sdr_api_Interface.SetDebugFlag_Native

可能您已经使用不同的类创建了头文件 i、 软件包SDR_API下的e SDR_API

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

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

您正在使用的dll仍在引用来自SDR_API类的对本机方法的调用。 它应该是SDR_API_接口类

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

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

来自SDR_API_接口的调用为- sdr_api.sdr_api_Interface.SetDebugFlag_Native

可能您已经使用不同的类创建了头文件 i、 软件包SDR_API下的e SDR_API

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

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

您正在使用的dll仍在引用来自SDR_API类的对本机方法的调用。 它应该是SDR_API_接口类


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

您可以从
SDR\u API\u接口添加相关代码吗
SDR\u API
?谢谢RonK,按要求添加了它们。我还没有包括所有代码,否则会变得有点笨拙,但是如果您需要其他任何东西,请告诉我。您可以从
SDR\u AP添加相关代码吗Ijava接口<代码> >代码> SDRAPI API >代码>谢谢RonK,按要求添加了它们。我还没有包含所有代码,否则会变得笨拙,但请告诉我如果你需要别的什么。谢谢你的响应!它们在同一个包中,Java类中的声明与C++类中的方法匹配。老实说,这没有任何意义。我所做的只是将它移动到另一个类,它停止工作。如果你认为有帮助,我可以发布完整的代码?@Ryan从错误中可以看出,它肯定无法在本机界面中加载该方法。你能发布机器生成的.h文件代码吗?谢谢,我按照要求添加了代码。请让我e知道你是否需要任何额外的信息。yeah很有魅力。这么严格的命名约定是如何实现的,真是太奇怪了。移动你的类——事情一定会打破的!感谢你的回复!它们在同一个包中,java类中的声明与