JavaH 无法为 JNI 创建 C 头文件 class
JavaH failing to create C header file for JNI class
这真的让我感到困惑,因为我已经尝试了关于 classpath 和其他各种事情的一切可能。我在 windows、linux 和 IDE 中尝试了各种不同的命令提示,但似乎无济于事。总是同样的错误。任何见解都会在这里有所帮助。
尝试使用以下命令 运行 javah 时出现以下错误:
javah -jni -cp jna-3.0.9.jar:java.nio.*:java.util.* CameraInterfaceLibrary
Error: Could not find class file for 'CameraInterfaceLibrary'.
我真的卡在这里了。我只是不明白为什么它拒绝生成头文件。无论我做什么,它总是说找不到 class 文件。我只是很困惑。我已经尝试了更简单的示例,但使用真实代码它无法正常工作。
代码如下:
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.win32.StdCallLibrary;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
/**
* JNA Wrapper for library <b>CameraInterface</b><br>
* This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
* a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
* For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
*/
public class CameraInterfaceLibrary implements StdCallLibrary {
public static final String JNA_LIBRARY_NAME = "CameraInterface";
public static final NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance(CameraInterfaceLibrary.JNA_LIBRARY_NAME);
static {
Native.loadLibrary(CameraInterfaceLibrary.JNA_LIBRARY_NAME, CameraInterfaceLibrary.class);
}
public static class DV_TM extends Structure {
/**
* Second.interval is [0.59] * /<br>
* int tm_min; /* To the value interval [0.59]
*/
public int tm_sec;
/** Value seconds interval [0.23] */
public int tm_hour;
/** The value date of the month interval [1.31] */
public int tm_mday;
/** The value date of the month interval [1.31] */
public int tm_mon;
/** Month (from the beginning of January, o behalf of the month) value interval [0.11] */
public int tm_year;
/** Year, its value is equal to the actual year as 2010 */
public int tm_wday;
/** The value range for the week [0.6], where O stands for Sunday, 1 for Monday, and so on */
public int tm_yday;
/** Number of days from the beginning of January 1 each year ranging from [0.365], where 0 represents January 1, 1 represents January 2, and so on, can be set to 0 */
public int tm_isdst;
public DV_TM() {
super();
}
protected List<? > getFieldOrder() {
return Arrays.asList("tm_sec", "tm_hour", "tm_mday", "tm_mon", "tm_year", "tm_wday", "tm_yday", "tm_isdst");
}
/**
* @param tm_sec Second.interval is [0.59] * /<br>
* int tm_min; /* To the value interval [0.59]<br>
* @param tm_hour Value seconds interval [0.23]<br>
* @param tm_mday The value date of the month interval [1.31]<br>
* @param tm_mon The value date of the month interval [1.31]<br>
* @param tm_year Month (from the beginning of January, o behalf of the month) value interval [0.11]<br>
* @param tm_wday Year, its value is equal to the actual year as 2010<br>
* @param tm_yday The value range for the week [0.6], where O stands for Sunday, 1 for Monday, and so on<br>
* @param tm_isdst Number of days from the beginning of January 1 each year ranging from [0.365], where 0 represents January 1, 1 represents January 2, and so on, can be set to 0
*/
public DV_TM(int tm_sec, int tm_hour, int tm_mday, int tm_mon, int tm_year, int tm_wday, int tm_yday, int tm_isdst) {
super();
this.tm_sec = tm_sec;
this.tm_hour = tm_hour;
this.tm_mday = tm_mday;
this.tm_mon = tm_mon;
this.tm_year = tm_year;
this.tm_wday = tm_wday;
this.tm_yday = tm_yday;
this.tm_isdst = tm_isdst;
}
/* JR - Removed as no deemed necessary at this point
public DV_TM(com.sun.jna.Pointer peer) {
super(peer);
}*/
public static class ByReference extends DV_TM implements Structure.ByReference {
};
public static class ByValue extends DV_TM implements Structure.ByValue {
};
};
/**
* Connected devices (connect with camera)<br>
* Original signature : <code>int CConnectDV()</code><br>
* <i>native declaration : line 18</i>
*/
public static native int CConnectDV();
/**
* Disconnect the device (disconnect with camera)<br>
* Original signature : <code>int CDisconnectDV()</code><br>
* <i>native declaration : line 20</i>
*/
public static native int CDisconnectDV();
/**
* Landing equipment parameters: password (connect and open the camera parameter: password)<br>
* Original signature : <code>int CLogin(char*)</code><br>
* <i>native declaration : line 22</i><br>
* @deprecated use the safer methods {@link #CLogin(java.nio.ByteBuffer)} and {@link #CLogin(com.sun.jna.Pointer)} instead
*/
public static native int CLogin(com.sun.jna.Pointer Password);
/**
* Landing equipment parameters: password (connect and open the camera parameter: password)<br>
* Original signature : <code>int CLogin(char*)</code><br>
* <i>native declaration : line 22</i>
*/
public static native int CLogin(ByteBuffer Password);
/**
* The school parameters: see DV-TM structure (timing parameter: look at the DV-TM structure)<br>
* Original signature : <code>int CSetTime(DV_TM*)</code><br>
* <i>native declaration : line 24</i>
*/
public static native int CSetTime(CameraInterfaceLibrary.DV_TM ptm);
/**
* Read machine time parameters: see DV-TM structure (read the machine time parameter: look at the DV-TM structure)<br>
* Original signature : <code>int CGetTime(DV_TM*)</code><br>
* <i>native declaration : line 26</i>
*/
public static native int CGetTime(CameraInterfaceLibrary.DV_TM ptm);
/**
* Set password parameters: password new password 6 (set password parameter: password 6 new password)<br>
* Original signature : <code>int CSetPassword(char*)</code><br>
* <i>native declaration : line 28</i><br>
* @deprecated use the safer methods {@link #CSetPassword(java.nio.ByteBuffer)} and {@link #CSetPassword(com.sun.jna.Pointer)} instead
*/
public static native int CSetPassword(com.sun.jna.Pointer Password);
/**
* Set password parameters: password new password 6 (set password parameter: password 6 new password)<br>
* Original signature : <code>int CSetPassword(char*)</code><br>
* <i>native declaration : line 28</i>
*/
public static native int CSetPassword(ByteBuffer Password);
/**
* Set the number parameter: ID Number 13 (set ID number parameter: 13 ID number)<br>
* Original signature : <code>int CSetID(char*)</code><br>
* <i>native declaration : line 30</i><br>
* @deprecated use the safer methods {@link #CSetID(java.nio.ByteBuffer)} and {@link #CSetID(com.sun.jna.Pointer)} instead
*/
public static native int CSetID(com.sun.jna.Pointer ID);
/**
* Set the number parameter: ID Number 13 (set ID number parameter: 13 ID number)<br>
* Original signature : <code>int CSetID(char*)</code><br>
* <i>native declaration : line 30</i>
*/
public static native int CSetID(ByteBuffer ID);
/**
* Read the number parameter: ID Number 13 (read ID number parameter: 13 ID number)<br>
* Original signature : <code>int CGetID(char*)</code><br>
* <i>native declaration : line 32</i><br>
* @deprecated use the safer methods {@link #CGetID(java.nio.ByteBuffer)} and {@link #CGetID(com.sun.jna.Pointer)} instead
*/
public static native int CGetID(com.sun.jna.Pointer ID);
/**
* Read the number parameter: ID Number 13 (read ID number parameter: 13 ID number)<br>
* Original signature : <code>int CGetID(char*)</code><br>
* <i>native declaration : line 32</i>
*/
public static native int CGetID(ByteBuffer ID);
/**
* Enter the U disk mode (Enter the U disk mode)<br>
* Original signature : <code>int CIntoUDiskMode()</code><br>
* <i>native declaration : line 34</i>
*/
public static native int CIntoUDiskMode();
}
当您使用 JNA 时,不再需要生成 C 头文件或编译任何本机代码。
使用直接映射时,声明的方法 native
会自动绑定到目标共享库中的相应方法。
JNA 使用方法签名和 StdCall
标记接口来确定如何将您的 Java 调用转换为具有适当类型转换的本机调用。
编辑
确保在静态初始化程序中调用 Native.register()
,而不是 Native.loadLibrary()
。如果您已经实现了工作模型,请在您的问题中添加注释。
您可以通过编写一个简单的 main
函数来测试执行情况,该函数会调用您的一个或多个方法。
其他人是正确的(如果您使用的是 JPA,则不需要 javah)。
但是为了彻底(并帮助您处理您可能 运行 进行 Java 开发的其他事情),我怀疑您问题的答案是您没有指定class路径正确。
这里是 javah 的文档:http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javah.html
我在您的命令行中看到的问题:
- 合适的参数是-classpath(不是-cp)
- 您需要使用分号而不是冒号分隔条目
- 您必须指定 classes 的根路径(如果这恰好是当前目录,您仍然必须使用“.”包含它)
- 必须指定依赖jar文件的路径
- 在任何情况下都不会向 class 路径添加类似导入的标识符(即 java.nio.* 是一个导入 - 与此处无关)
- 如果您的 class 在包裹中(您应该这样做!),那么您需要将其包含在 classname
中
在普通项目中(其中 classes 和依赖的 jar 存储在单独的文件夹中),我会使用这样的东西:
javah -jni -classpath C:\MyApp\Classes;C:\MyApp\lib\* com.myapp.MyAppLibrary
注意使用通配符加载 lib\ 文件夹中的所有 jar 文件。
这真的让我感到困惑,因为我已经尝试了关于 classpath 和其他各种事情的一切可能。我在 windows、linux 和 IDE 中尝试了各种不同的命令提示,但似乎无济于事。总是同样的错误。任何见解都会在这里有所帮助。
尝试使用以下命令 运行 javah 时出现以下错误:
javah -jni -cp jna-3.0.9.jar:java.nio.*:java.util.* CameraInterfaceLibrary
Error: Could not find class file for 'CameraInterfaceLibrary'.
我真的卡在这里了。我只是不明白为什么它拒绝生成头文件。无论我做什么,它总是说找不到 class 文件。我只是很困惑。我已经尝试了更简单的示例,但使用真实代码它无法正常工作。
代码如下:
import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.win32.StdCallLibrary;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
/**
* JNA Wrapper for library <b>CameraInterface</b><br>
* This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
* a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
* For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
*/
public class CameraInterfaceLibrary implements StdCallLibrary {
public static final String JNA_LIBRARY_NAME = "CameraInterface";
public static final NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance(CameraInterfaceLibrary.JNA_LIBRARY_NAME);
static {
Native.loadLibrary(CameraInterfaceLibrary.JNA_LIBRARY_NAME, CameraInterfaceLibrary.class);
}
public static class DV_TM extends Structure {
/**
* Second.interval is [0.59] * /<br>
* int tm_min; /* To the value interval [0.59]
*/
public int tm_sec;
/** Value seconds interval [0.23] */
public int tm_hour;
/** The value date of the month interval [1.31] */
public int tm_mday;
/** The value date of the month interval [1.31] */
public int tm_mon;
/** Month (from the beginning of January, o behalf of the month) value interval [0.11] */
public int tm_year;
/** Year, its value is equal to the actual year as 2010 */
public int tm_wday;
/** The value range for the week [0.6], where O stands for Sunday, 1 for Monday, and so on */
public int tm_yday;
/** Number of days from the beginning of January 1 each year ranging from [0.365], where 0 represents January 1, 1 represents January 2, and so on, can be set to 0 */
public int tm_isdst;
public DV_TM() {
super();
}
protected List<? > getFieldOrder() {
return Arrays.asList("tm_sec", "tm_hour", "tm_mday", "tm_mon", "tm_year", "tm_wday", "tm_yday", "tm_isdst");
}
/**
* @param tm_sec Second.interval is [0.59] * /<br>
* int tm_min; /* To the value interval [0.59]<br>
* @param tm_hour Value seconds interval [0.23]<br>
* @param tm_mday The value date of the month interval [1.31]<br>
* @param tm_mon The value date of the month interval [1.31]<br>
* @param tm_year Month (from the beginning of January, o behalf of the month) value interval [0.11]<br>
* @param tm_wday Year, its value is equal to the actual year as 2010<br>
* @param tm_yday The value range for the week [0.6], where O stands for Sunday, 1 for Monday, and so on<br>
* @param tm_isdst Number of days from the beginning of January 1 each year ranging from [0.365], where 0 represents January 1, 1 represents January 2, and so on, can be set to 0
*/
public DV_TM(int tm_sec, int tm_hour, int tm_mday, int tm_mon, int tm_year, int tm_wday, int tm_yday, int tm_isdst) {
super();
this.tm_sec = tm_sec;
this.tm_hour = tm_hour;
this.tm_mday = tm_mday;
this.tm_mon = tm_mon;
this.tm_year = tm_year;
this.tm_wday = tm_wday;
this.tm_yday = tm_yday;
this.tm_isdst = tm_isdst;
}
/* JR - Removed as no deemed necessary at this point
public DV_TM(com.sun.jna.Pointer peer) {
super(peer);
}*/
public static class ByReference extends DV_TM implements Structure.ByReference {
};
public static class ByValue extends DV_TM implements Structure.ByValue {
};
};
/**
* Connected devices (connect with camera)<br>
* Original signature : <code>int CConnectDV()</code><br>
* <i>native declaration : line 18</i>
*/
public static native int CConnectDV();
/**
* Disconnect the device (disconnect with camera)<br>
* Original signature : <code>int CDisconnectDV()</code><br>
* <i>native declaration : line 20</i>
*/
public static native int CDisconnectDV();
/**
* Landing equipment parameters: password (connect and open the camera parameter: password)<br>
* Original signature : <code>int CLogin(char*)</code><br>
* <i>native declaration : line 22</i><br>
* @deprecated use the safer methods {@link #CLogin(java.nio.ByteBuffer)} and {@link #CLogin(com.sun.jna.Pointer)} instead
*/
public static native int CLogin(com.sun.jna.Pointer Password);
/**
* Landing equipment parameters: password (connect and open the camera parameter: password)<br>
* Original signature : <code>int CLogin(char*)</code><br>
* <i>native declaration : line 22</i>
*/
public static native int CLogin(ByteBuffer Password);
/**
* The school parameters: see DV-TM structure (timing parameter: look at the DV-TM structure)<br>
* Original signature : <code>int CSetTime(DV_TM*)</code><br>
* <i>native declaration : line 24</i>
*/
public static native int CSetTime(CameraInterfaceLibrary.DV_TM ptm);
/**
* Read machine time parameters: see DV-TM structure (read the machine time parameter: look at the DV-TM structure)<br>
* Original signature : <code>int CGetTime(DV_TM*)</code><br>
* <i>native declaration : line 26</i>
*/
public static native int CGetTime(CameraInterfaceLibrary.DV_TM ptm);
/**
* Set password parameters: password new password 6 (set password parameter: password 6 new password)<br>
* Original signature : <code>int CSetPassword(char*)</code><br>
* <i>native declaration : line 28</i><br>
* @deprecated use the safer methods {@link #CSetPassword(java.nio.ByteBuffer)} and {@link #CSetPassword(com.sun.jna.Pointer)} instead
*/
public static native int CSetPassword(com.sun.jna.Pointer Password);
/**
* Set password parameters: password new password 6 (set password parameter: password 6 new password)<br>
* Original signature : <code>int CSetPassword(char*)</code><br>
* <i>native declaration : line 28</i>
*/
public static native int CSetPassword(ByteBuffer Password);
/**
* Set the number parameter: ID Number 13 (set ID number parameter: 13 ID number)<br>
* Original signature : <code>int CSetID(char*)</code><br>
* <i>native declaration : line 30</i><br>
* @deprecated use the safer methods {@link #CSetID(java.nio.ByteBuffer)} and {@link #CSetID(com.sun.jna.Pointer)} instead
*/
public static native int CSetID(com.sun.jna.Pointer ID);
/**
* Set the number parameter: ID Number 13 (set ID number parameter: 13 ID number)<br>
* Original signature : <code>int CSetID(char*)</code><br>
* <i>native declaration : line 30</i>
*/
public static native int CSetID(ByteBuffer ID);
/**
* Read the number parameter: ID Number 13 (read ID number parameter: 13 ID number)<br>
* Original signature : <code>int CGetID(char*)</code><br>
* <i>native declaration : line 32</i><br>
* @deprecated use the safer methods {@link #CGetID(java.nio.ByteBuffer)} and {@link #CGetID(com.sun.jna.Pointer)} instead
*/
public static native int CGetID(com.sun.jna.Pointer ID);
/**
* Read the number parameter: ID Number 13 (read ID number parameter: 13 ID number)<br>
* Original signature : <code>int CGetID(char*)</code><br>
* <i>native declaration : line 32</i>
*/
public static native int CGetID(ByteBuffer ID);
/**
* Enter the U disk mode (Enter the U disk mode)<br>
* Original signature : <code>int CIntoUDiskMode()</code><br>
* <i>native declaration : line 34</i>
*/
public static native int CIntoUDiskMode();
}
当您使用 JNA 时,不再需要生成 C 头文件或编译任何本机代码。
使用直接映射时,声明的方法 native
会自动绑定到目标共享库中的相应方法。
JNA 使用方法签名和 StdCall
标记接口来确定如何将您的 Java 调用转换为具有适当类型转换的本机调用。
编辑
确保在静态初始化程序中调用 Native.register()
,而不是 Native.loadLibrary()
。如果您已经实现了工作模型,请在您的问题中添加注释。
您可以通过编写一个简单的 main
函数来测试执行情况,该函数会调用您的一个或多个方法。
其他人是正确的(如果您使用的是 JPA,则不需要 javah)。
但是为了彻底(并帮助您处理您可能 运行 进行 Java 开发的其他事情),我怀疑您问题的答案是您没有指定class路径正确。
这里是 javah 的文档:http://docs.oracle.com/javase/7/docs/technotes/tools/windows/javah.html
我在您的命令行中看到的问题:
- 合适的参数是-classpath(不是-cp)
- 您需要使用分号而不是冒号分隔条目
- 您必须指定 classes 的根路径(如果这恰好是当前目录,您仍然必须使用“.”包含它)
- 必须指定依赖jar文件的路径
- 在任何情况下都不会向 class 路径添加类似导入的标识符(即 java.nio.* 是一个导入 - 与此处无关)
- 如果您的 class 在包裹中(您应该这样做!),那么您需要将其包含在 classname 中
在普通项目中(其中 classes 和依赖的 jar 存储在单独的文件夹中),我会使用这样的东西:
javah -jni -classpath C:\MyApp\Classes;C:\MyApp\lib\* com.myapp.MyAppLibrary
注意使用通配符加载 lib\ 文件夹中的所有 jar 文件。