1 概述

(1)项目开发过程可能涉及多种语言,而多种语言之间如何数据交换格式是多种多样的,比如说:Java和JavaScript可以用json,Java和C#可以用xml等等。

(2)这里提供一种C与Java数据交换格式:struct <-> byte[] <-> javaBean

  • C不是一门面向对象的语言,但是C有结构体(struct),C一般操作结构体。
  • Java是一门面向对象的语言,所以Java一般操作对象。
  • 选择byte数组作为传输格式,节省通信成本,没有多余内容,不过极度依赖接收方与发送方之间的配合,毕竟如果字段错乱,将导致解析失败。

2 C语言:struct -> byte[]

#include <stdio.h>
#include <stdlib.h>
#include <mem.h> struct SS {
int f;
int d;
short g;
}; //结构定义 int main() {
unsigned char *b; // byte 指针
int N, i;
struct SS s = {7, 8, 4}; //声明一个结构对象并初始化
N = sizeof(struct SS); //结构大小
b = (unsigned char *) malloc(N); //动态分配b
memcpy(b, &s, sizeof(struct SS)); //内容复制
printf("%d", N);
for (int i = 0; i < N; i++) {
if (i > 0)
printf(",");
printf("%d", b[i]);
}
return 0;
}

3 Java语言:byte[] -> JavaBean

(1)方法1:依赖Unsafe类的数组操作接口

public class BytesToBean {
static class SS {
private int f;
private int d;
private short g;
// 省略getter和setter 构造方法 toString方法
} private static Unsafe unsafe; static {
try {
Field f = f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
unsafe = (Unsafe) f.get(null);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
} public static void main(String[] args){
//struct SS {
// int f;
// int d;
// short g;
//}; //结构体定义
byte[] bs = new byte[]{4, 0, 0, 0, 7, 0, 0, 0, 8, 0};
int offset = 0;
SS ss = new SS();
Field[] declaredFields = SS.class.getDeclaredFields();
for (Field declaredField : declaredFields) {
Class<?> clazz = declaredField.getType();
switch (clazz.getTypeName()) {
case "int":
int intValue = unsafe.getInt(bs, Unsafe.ARRAY_BYTE_BASE_OFFSET + offset);
unsafe.putInt(ss, unsafe.objectFieldOffset(declaredField), intValue);
break;
case "short":
short shortValue = unsafe.getShort(bs, Unsafe.ARRAY_BYTE_BASE_OFFSET + offset);
unsafe.putShort(ss, unsafe.objectFieldOffset(declaredField), shortValue);
break;
}
offset += getFiledLength(clazz);
}
System.out.println(ss); // SS{f=4, d=7, g=8}
} private static int getFiledLength(Class clazz){
Object o = Array.newInstance(clazz, 0);
return unsafe.arrayIndexScale(o.getClass());
} }

(2)方法2:依赖ByteBuffer类的接口

public class BytesToBeans {
static class SS {
private int f;
private int d;
private short g;
// 省略getter和setter 构造方法 toString方法
} private static Unsafe unsafe; static {
try {
Field f = f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
unsafe = (Unsafe) f.get(null);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
} public static void main(String[] args) {
byte[] bs = new byte[]{4, 0, 0, 0, 7, 0, 0, 0, 8, 0};
ByteBuffer byteBuffer = ByteBuffer.wrap(bs);
byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
SS ss = new SS();
Field[] declaredFields = UnsafeTest.SS.class.getDeclaredFields();
for (Field declaredField : declaredFields) {
Class<?> clazz = declaredField.getType();
switch (clazz.getTypeName()) {
case "int":
int intValue = byteBuffer.getInt();
// unsafe.objectFieldOffset(declaredField) 获取该字段的偏移量
// Java对象:对象头 常量池数组 字段 方法
// 请参考:https://www.cnblogs.com/linzhanfly/p/9552910.html
unsafe.putInt(ss, unsafe.objectFieldOffset(declaredField), intValue);
break;
case "short":
short shortValue = byteBuffer.getShort();
unsafe.putShort(ss, unsafe.objectFieldOffset(declaredField), shortValue);
break;
}
}
System.out.println(ss); // SS{f=4, d=7, g=8}
}
}

4 总结

  • C与Java传输格式为byte数组,总体流程:struct <-> byte[] <-> javaBean。
  • C不熟悉
  • Java依赖Unsafe的对象字段赋值操作API、反射机制和ByteBuffer的byte数组操作API

最后,这也许不是最好的方案,我也不知道是否有更优秀的方案......

C结构体与JavaBean转化的更多相关文章

  1. C#结构体数组间的转化

    转自:http://developer.51cto.com/art/200908/143779.htm 解决C#结构体数组间的转化问题的由来:在写C#TCP通信程序时,发送数据时,如果是和VC6.0等 ...

  2. c#中关于结构体和字节数组转化

    最近在使用结构体与字节数组转化来实现socket间数据传输.现在开始整理一下.对于Marshal可以查阅msdn,关于字节数组与结构体转代码如下: using System; using System ...

  3. C++/C#结构体转化-二维数组-bytes To Strings

    C++结构体 typedef struct VidyoClientRequestGetWindowsAndDesktops_ { /*! The number of application windo ...

  4. 字节转化为结构体BytesToStruct

    //结构体转字节数组 public byte[] StructToBytes (object structObj) { int size = Marshal.SizeOf (structObj);// ...

  5. C#基础回顾(二)—页面值传递、重载与重写、类与结构体、装箱与拆箱

    一.前言 -孤独的路上有梦想作伴,乘风破浪- 二.页面值传递 (1)C#各页面之间可以进行数据的交换和传递,页面之间可根据获取的数据,进行各自的操作(跳转.计算等操作).为了实现多种方式的数据传递,C ...

  6. HDOJ 1009. Fat Mouse' Trade 贪心 结构体排序

    FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  7. swift 的枚举、结构体、类

    一.Swift的枚举 枚举是一系相关联的值定义的一个公共的组类型,同时能够让你在编程的时候在类型安全的情况下去使用这些值.Swift中的枚举比OC中的枚举强大得多, 因为Swift中的枚举是一等类型, ...

  8. C#调用C/C++动态库 封送结构体,结构体数组

    一. 结构体的传递 #define JNAAPI extern "C" __declspec(dllexport) // C方式导出函数 typedef struct { int ...

  9. c# 利用结构体获取json数据

    最近做微信支付,要获取用户的openid,调用接口后返回的是json格式的数据,我想在c#后台把数据逐一取出,网上查了查,找到以下方法: 1.首先调用接口,要有一个post数据到指定url并返回数据的 ...

随机推荐

  1. redhat 7.6下如何更新YUM源(仓库)?

    1. 安装epel-release     yum install epel-release 2. 安装webstatic-release     rpm -Uvh https://mirror.we ...

  2. SQL-W3School-高级:SQL LIKE 操作符

    ylbtech-SQL-W3School-高级:SQL LIKE 操作符 1.返回顶部 1. LIKE 操作符用于在 WHERE 子句中搜索列中的指定模式. LIKE 操作符 LIKE 操作符用于在 ...

  3. Android开发final的用法

    Android开发final的用法   final如果修饰类,该类不能被继承: final如果修饰变量,该变量不能被修改,不能再重新赋值,即变为常量: final如果修饰方法,该方法不能被重写: 此外 ...

  4. WebService技术规则

    1.基于web的系统级接口规范     - 一个普通适用标准 :http+xml     - 任何网络通信的操作系统     - 自包含.自描述.模块化     - 发布.定位.通过web调用  2. ...

  5. python md5验签

    import hashlib #api验签 参数按首字母排序,然后拼接clientid=123456&num=xxxx&status=1&timestamp=157319776 ...

  6. 【leetcode】521. Longest Uncommon Subsequence I

    problem 521. Longest Uncommon Subsequence I 最长非共同子序列之一 题意: 两个字符串的情况很少,如果两个字符串相等,那么一定没有非共同子序列,反之,如果两个 ...

  7. 百度之星2019第一场1002 Game

    思路: 离散化之后dp,dp[i][j]表示完成前i个任务并且处在第j个点所需要的最小代价. 实现: #include <bits/stdc++.h> using namespace st ...

  8. 彻底搞定Javascript事件循环

    参考链接:https://juejin.im/post/5dca8a8be51d45227239abc4?utm_medium=hao.caibaojian.com&utm_source=ha ...

  9. SpringBoot整合Redis及Redis工具类

    前言 想做一个秒杀项目,问了几个大佬要了项目视频,结果,自己本地实践的时候,发现不太一样,所以写下这篇,为以后做准备. 环境配置 IDE:IDEA 环境:Windows 数据库:Redis Maven ...

  10. Java Netty和Android之WebSocket,Springboot和Vue项目网址

    在Netty上使用Websocket和网页上写个简单的websocket https://www.cnblogs.com/amibandoufu/p/11442881.html Android上使用w ...