惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - Franky
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
美团技术团队
The Cloudflare Blog
量子位
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园_首页
F
Fortinet All Blogs
J
Java Code Geeks
人人都是产品经理
人人都是产品经理
N
Netflix TechBlog - Medium
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
爱范儿
爱范儿
Apple Machine Learning Research
Apple Machine Learning Research
B
Blog RSS Feed
博客园 - 聂微东
Hugging Face - Blog
Hugging Face - Blog
WordPress大学
WordPress大学
小众软件
小众软件
Y
Y Combinator Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Vercel News
Vercel News
S
SegmentFault 最新的问题
有赞技术团队
有赞技术团队

祈雨的笔记

安全多方计算MPC spark原理解析 kueue执行源码分析 spark on k8s执行源码分析 spark-operator源码解析 系统压测遇到的缓存击穿问题 我的世界PC与安卓联机 蚂蚁金服流量投放平台的AIG改造 G1大对象致Old区占用率高 日志打印导致接口响应率下跌分析 Groovy加载类导致OOM分析 ERROR日志打印导致CPU满载 记OceanBase死锁超时 应用发版期间服务响应超时 Ark Serverless初探 系统优化复盘一二三 The user specified as a definer does not exist Kong网关初探 API网关选型调研 CPU火焰图常用工具 配置中心选型调研 root操作Nginx导致用户组错误 基于Proxifier使用代理 FastJSON字段智能匹配踩坑 Nacos初探 记一次Nginx服务器CPU满荷载故障 基于券系统分库分表的思考 limit不参与SQL成本计算致索引失效 Linux常用性能监控命令 golang低版本http2偶现400
java与c通信实现方案
祈雨的笔记 · 2017-12-05 · via 祈雨的笔记

Java与c通信,最大的问题就是Java数据和c数据的转换问题。最近我做的项目就是java与c通过蓝牙通信,难点就是java数据结构和c结构体数据的转换问题。
通过几天的研究,实际上这个问题还是比较容易解决的,并以java自制了一个自动转换两者数据结构的工具。
Java和c两者通信都是通过流获取以及发送字节,只需要将数据结构解析成对应语言平台的字节数组,以及字节数组组装成对应语言平台的数据结构即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118



#include "stdafx.h"
#include <stdio.h>
#include <winsock2.h>
#include <string.h>

#pragma comment(lib,"ws2_32.lib")


typedef struct Books
{
char title[10];
char name;

int int_id[2];
unsigned short int short_id;
float book_id;
};

int main(int argc, char* argv[])
{

WORD sockVersion = MAKEWORD(2, 2);
WSADATA wsaData;
if (WSAStartup(sockVersion, &wsaData) != 0)
{
return 0;
}


SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (slisten == INVALID_SOCKET)
{
printf("socket error !");
return 0;
}


sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_port = htons(8888);
sin.sin_addr.S_un.S_addr = INADDR_ANY;
if (bind(slisten, (LPSOCKADDR)&sin, sizeof(sin)) == SOCKET_ERROR)
{
printf("bind error !");
}


if (listen(slisten, 5) == SOCKET_ERROR)
{
printf("listen error !");
return 0;
}


SOCKET sClient;
sockaddr_in remoteAddr;
int nAddrlen = sizeof(remoteAddr);
char revData[255];
while (true)
{
printf("\n等待连接...\n");
sClient = accept(slisten, (SOCKADDR *)&remoteAddr, &nAddrlen);
if (sClient == INVALID_SOCKET)
{
printf("accept error !");
continue;
}
printf("接受到一个连接:%s \r\n", inet_ntoa(remoteAddr.sin_addr));


struct Books revBook;
int ret = recv(sClient, revData, sizeof(Books), 0);
if (ret > 0)
{
for(int i=0;i<sizeof(Books);i++){
printf("%d,",revData[i]);
}
printf("\n");
memcpy(&revBook, revData, sizeof(revBook));
printf("title:%s\n",revBook.title);
printf("name:%c\n",revBook.name);
printf("short_id:%d\n",revBook.short_id);
printf("int_id[0]:%d\n",revBook.int_id[0]);
printf("int_id[1]:%d\n",revBook.int_id[1]);
printf("book_id:%f\n",revBook.book_id);
}

struct Books book;
strcpy_s(book.title, "hello-c1");
book.name = 'a';
book.int_id[0] = 253;
book.int_id[1] = 13;
book.book_id = 22.2;
book.short_id = -34;

char snd_buf[sizeof(book)];
memset(snd_buf, 0, sizeof(book));
memcpy(snd_buf, &book, sizeof(book));

printf("\nlen:%d\n",sizeof(book));
printf("\nlen:%d\n",sizeof(snd_buf));
send(sClient, snd_buf, sizeof(snd_buf), 0);

printf("发送:\n");
for(int i=0;i<sizeof(snd_buf);i++){
printf("%d,",snd_buf[i]);
}

closesocket(sClient);
}

closesocket(slisten);
WSACleanup();
return 0;
}

方法com.wxtx.java2c.reflect.TXDataReader.needAlign(int, int)的作用是c结构体中的字节对齐功能。默认是按结构体中最长的字段进行字节对齐。例如例子中最长字段时float类型的book_id,所以以4字节对齐。
实际情况中c可能是其他对齐方式,根据需要可以修改该方法。