解决JNA 高版本使用结构体时出现 java.lang.Error: Structure.getFieldOrder()

文章介绍了在Java使用JNA(JavaNativeAccess)时,如何定义结构体字段的顺序。方法一是使用@Structure.FieldOrder注解,明确指定结构体字段的排列;方法二是创建一个抽象的FieldStructure类,自定义getFieldOrder方法,动态获取结构体的字段顺序。这两种方法都能帮助确保结构体在内存中的布局与C/C++保持一致。

方法一:

在结构体的类上@Structure.FieldOrder注解,将结构体的每个字段都填入注解中

 @Structure.FieldOrder({"wMainEventType","wSubEventType","byRes"})
 public class NET_DVR_EVENT_LINKAGE_INFO extends Structure {
        public short wMainEventType;                   
        public short wSubEventType;                     
        public byte[] byRes = new byte[28];
 }

方法二:

构建一个结构体公共类,继承jna里面的Structure类,并实现getFieldOrder该方法,自定义结构体的字段获取方法

public abstract class FieldStructure extends Structure implements Serializable {

    @Override
    protected List<String> getFieldOrder() {
        List<String> fieldOrderList = new ArrayList<>();
        for (Class<?> cls = getClass();
             !cls.equals(FieldStructure.class);
             cls = cls.getSuperclass()) {
            Field[] fields = cls.getDeclaredFields();
            int modifiers;
            for (Field field : fields) {
10:19:30.205 [main] ERROR o.s.b.SpringApplication - [reportFailure,870] - Application run failed org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'insCommController': Unsatisfied dependency expressed through field 'hkCameraAlarm'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hkCameraAlarmImpl': Invocation of init method failed; nested exception is java.lang.Error: Structure.getFieldOrder() on class com.ruoyi.sac.acsUser.NetSDKDemo.HCNetSDK$NET_DVR_DEVICEINFO_V30 does not provide enough names [0] ([]) to match declared fields [31] ([byAlarmInPortNum, byAlarmOutPortNum, byAudioChanNum, byChanNum, byDVRType, byDiskNum, byHighDChanNum, byIPChanNum, byLanguageType, byMainProto, byMirrorChanNum, byMultiStreamProto, byRes2, byStartChan, byStartDChan, byStartDTalkChan, byStartVoiceInChanNo, bySubProto, bySupport, bySupport1, bySupport2, bySupport3, bySupport4, bySupport5, bySupport6, bySupport7, byVoiceInChanNum, byZeroChanNum, sSerialNumber, wDevType, wStartMirrorChanNo]) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:660) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640) at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1431) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:920) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:780) at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:453) at org.springframework.boot.SpringApplication.run(SpringApplication.java:343) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1370) at org.springframework.boot.SpringApplication.run(SpringApplication.java:1359) at com.ruoyi.RuoYiApplication.main(RuoYiApplication.java:39) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:49) at org.springframework.boot.loader.Launcher.launch(Launcher.java:108) at org.springframework.boot.loader.Launcher.launch(Launcher.java:58) at org.springframework.boot.loader.WarLauncher.main(WarLauncher.java:59) Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'hkCameraAlarmImpl': Invocation of init method failed; nested exception is java.lang.Error: Structure.getFieldOrder() on class com.ruoyi.sac.acsUser.NetSDKDemo.HCNetSDK$NET_DVR_DEVICEINFO_V30 does not provide enough names [0] ([]) to match declared fields [31] ([byAlarmInPortNum, byAlarmOutPortNum, byAudioChanNum, byChanNum, byDVRType, byDiskNum, byHighDChanNum, byIPChanNum, byLanguageType, byMainProto, byMirrorChanNum, byMultiStreamProto, byRes2, byStartChan, byStartDChan, byStartDTalkChan, byStartVoiceInChanNo, bySubProto, bySupport, bySupport1, bySupport2, bySupport3, bySupport4, bySupport5, bySupport6, bySupport7, byVoiceInChanNum, byZeroChanNum, sSerialNumber, wDevType, wStartMirrorChanNo]) at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:160) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:440) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391) at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311) at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657) ... 28 common frames omitted Caused by: java.lang.Error: Structure.getFieldOrder() on class com.ruoyi.sac.acsUser.NetSDKDemo.HCNetSDK$NET_DVR_DEVICEINFO_V30 does not provide enough names [0] ([]) to match declared fields [31] ([byAlarmInPortNum, byAlarmOutPortNum, byAudioChanNum, byChanNum, byDVRType, byDiskNum, byHighDChanNum, byIPChanNum, byLanguageType, byMainProto, byMirrorChanNum, byMultiStreamProto, byRes2, byStartChan, byStartDChan, byStartDTalkChan, byStartVoiceInChanNo, bySubProto, bySupport, bySupport1, bySupport2, bySupport3, bySupport4, bySupport5, bySupport6, bySupport7, byVoiceInChanNum, byZeroChanNum, sSerialNumber, wDevType, wStartMirrorChanNo]) at com.sun.jna.Structure.getFields(Structure.java:1110) at com.sun.jna.Structure.deriveLayout(Structure.java:1265) at com.sun.jna.Structure.calculateSize(Structure.java:1192) at com.sun.jna.Structure.allocateMemory(Structure.java:413) at com.sun.jna.Structure.ensureAllocated(Structure.java:389) at com.sun.jna.Structure.ensureAllocated(Structure.java:379) at com.sun.jna.Structure.size(Structure.java:446) at com.sun.jna.Structure.size(Structure.java:1170) at com.sun.jna.Native.getNativeSize(Native.java:1404) at com.sun.jna.Structure.getNativeSize(Structure.java:2310) at com.sun.jna.Structure.getNativeSize(Structure.java:2300) at com.sun.jna.Structure.validateField(Structure.java:1242) at com.sun.jna.Structure.validateFields(Structure.java:1255) at com.sun.jna.Structure.<init>(Structure.java:211) at com.sun.jna.Structure.<init>(Structure.java:204) at com.sun.jna.Structure.<init>(Structure.java:191) at com.sun.jna.Structure.<init>(Structure.java:183) at com.ruoyi.sac.acsUser.NetSDKDemo.HCNetSDK$NET_DVR_DEVICEINFO_V40.<init>(HCNetSDK.java:3899) at com.ruoyi.sac.acsUser.Acs.AcsMain.loginDevice(AcsMain.java:250) at com.ruoyi.sac.acsUser.Acs.AcsMain.initAsc(AcsMain.java:101) at com.ruoyi.sac.service.impl.hkCameraAlarmImpl.init(hkCameraAlarmImpl.java:49) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:389) at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeInitMethods(InitDestroyAnnotationBeanPostProcessor.java:333) at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:157) ... 40 common frames omitted
06-18
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值