参考:https://blog.csdn.net/qq_31094099/article/details/80790346
https://www.cnblogs.com/qicosmos/p/3601737.html
https://bbs.csdn.net/topics/390382122?page=1
https://blog.csdn.net/qq_29757283/article/details/83503581
工作中遇到了一个问题,在针对postgres源码和KPU对接的程序编写时,发现kpu的kernel函数的参数只能添加基础数据类型,我们无法将源码中的结构体发给kernel函数,所以我们要将结构体转换成int或者char等基础数据类型的数组来处理。
Demo程序
// C语言中结构体与字符数组之间的相互转换.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "pch.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
typedef struct Score
{
int math;
int chinese;
int english;
//int physics;
//int chemistry;
//int biology;
/*
Score(int m, int c, int e) :math(m), chinese(c), english(e)
{
}
void print()
{
printf("math:%d,chinese:%d,english:%d\n", math, chinese, english);
}
*/
}Score;
/*
#pragma pack(push)//保存对齐状态
#pragma pack(1)
typedef struct strcChange
{
unsigned char A;
unsigned int B;
unsigned double C;
const char *D;
}STRU_CHANGE;
#pragma pack(pop)
*/
//如果在未加字节对齐的情况下,那么需要字节对齐,
//那么直接将结构体取地址后复制到另一个数组中,实际上所需占用的内存大小是8个byte。
typedef struct strcChange
{
Score sco;
unsigned char A;
unsigned int B;
float C;
const char *D;
}STRU_CHANGE;
int main()
{
STRU_CHANGE obj1;
STRU_CHANGE *ptr;
obj1.A = 'a';
obj1.B = 5;
obj1.C = 12.5;
obj1.D = "hello";
char *buf=new char[sizeof(STRU_CHANGE)];
std::cout << sizeof(Score) << std::endl;
std::cout<< sizeof(STRU_CHANGE) <<std::endl;
printf("转换前数据结构内容:A=%c,B=%d,C=%f,D=%s\n",obj1.A,obj1.B,obj1.C, obj1.D);
memcpy(buf,&obj1,sizeof(obj1));
ptr = (STRU_CHANGE*)((char*)buf);
printf("从字符数组中获取数据结构:A=%c,B=%d,C=%f,D=%s\n", ptr->A, ptr->B, ptr->C, ptr->D);
std::cout << ptr->D << std::endl;
delete []buf;
buf=nullptr;
return 0;
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
// 入门提示:
// 1. 使用解决方案资源管理器窗口添加/管理文件
// 2. 使用团队资源管理器窗口连接到源代码管理
// 3. 使用输出窗口查看生成输出和其他消息
// 4. 使用错误列表窗口查看错误
// 5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
// 6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
转换前数据结构内容: A=a,B=5,C=12.500000,D=hello
字符数组获取数据结构:A=a,B=5,C=12.500000,D=hello
我想到了另一个问题,如果期间把buf指针转换成其他数据类型的指针进行操作会有什么结果,我们知道,如果是普通的同类型指针互相赋值,那么不管是那个指针都会改变指针地址保存的值,不同类型的实际上也是一样的,实验如下。加入方法fun。
void fun(char *buf) //传入的是指针 即使类型转换 还是会变化
{
STRU_CHANGE *temp = NULL;
temp= (STRU_CHANGE*)((char*)buf);
temp->A = 'A';
printf("temp获取数据结构:A=%c,B=%d,C=%f,D=%s\n", temp->A, temp->B, temp->C, temp->D);
}
int main()
{
STRU_CHANGE obj1;
STRU_CHANGE *ptr=NULL;
obj1.A = 'a';
obj1.B = 5;
obj1.C = 12.5;
obj1.D = "hello";
char *buf=new char[sizeof(STRU_CHANGE)];
std::cout << sizeof(Score) << std::endl;
std::cout<< sizeof(STRU_CHANGE) <<std::endl;
printf("转换前数据结构内容: A=%c,B=%d,C=%f,D=%s\n",obj1.A,obj1.B,obj1.C, obj1.D);
//printf("字符数组获取数据结构:A=%c,B=%d,C=%f,D=%s\n", ptr->A, ptr->B, ptr->C, ptr->D);
memcpy(buf,&obj1,sizeof(obj1));
fun(buf);//加入这个
ptr = (STRU_CHANGE*)((char*)buf);
printf("字符数组获取数据结构:A=%c,B=%d,C=%f,D=%s\n", ptr->A, ptr->B, ptr->C, ptr->D);
std::cout << ptr->D << std::endl;
delete []buf;
buf=nullptr;
return 0;
}
12
48
转换前数据结构内容: A=a,B=5,C=12.500000,D=hello
temp获取数据结构:A=A,B=5,C=12.500000,D=hello
字符数组获取数据结构:A=A,B=5,C=12.500000,D=hello
hello
发现temp和最后的答案都变了,验证了假设。
结构体中嵌套结构体
// 结构体转换.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
/*
工作需要将postgres源码中的结构体
*/
#include "pch.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
typedef struct Score
{
int math;
int chinese;
int english;
//int physics;
//int chemistry;
//int biology;
Score() = default;
Score(int m, int c, int e) :math(m), chinese(c), english(e)
{
}
/*
void print()
{
printf("math:%d,chinese:%d,english:%d\n", math, chinese, english);
}
*/
}Score;
//如果在未加字节对齐的情况下,那么需要字节对齐,
//那么直接将结构体取地址后复制到另一个数组中,实际上所需占用的内存大小是8个byte。
typedef struct STRU_CHANGE
{
Score sco;
unsigned char A;
unsigned int B;
float C;
char *D;//有了非静态const属性 默认构造函数会被删除
STRU_CHANGE() = default;
}STRU_CHANGE;
int main()
{
STRU_CHANGE obj1;
STRU_CHANGE *ptr;
Score temp(1,2,3);
obj1.sco = temp;
obj1.A = 'a';
obj1.B = 5;
obj1.C = 12.5;
obj1.D = new char[6];
strcpy(obj1.D, "hello");
char *buf = new char[sizeof(STRU_CHANGE)];
//std::cout << sizeof(Score) << std::endl;
std::cout << sizeof(STRU_CHANGE) << std::endl;
printf("转换前数据结构内容:score:math=%d,score:chinese=%d,score:english=%d,A=%c,B=%d,C=%f,D=%s\n",obj1.sco.math, obj1.sco.chinese, obj1.sco.english, obj1.A, obj1.B, obj1.C, obj1.D);
memcpy(buf, &obj1, sizeof(obj1));
ptr = (STRU_CHANGE*)((char*)buf);
std::cout << sizeof(*ptr) << std::endl;
printf("从字符数组中获取数据结构:score:math=%d,score:chinese=%d,score:english=%d,A=%c,B=%d,C=%f,D=%s\n", ptr->sco.math, ptr->sco.chinese, ptr->sco.english, ptr->A, ptr->B, ptr->C, ptr->D);
//std::cout << ptr->D << std::endl;
delete[]buf;
buf = nullptr;
return 0;
}
28
转换前数据结构内容:score:math=1,score:chinese=2,score:english=3,A=a,B=5,C=12.500000,D=hello
28
从字符数组中获取数据结构:score:math=1,score:chinese=2,score:english=3,A=a,B=5,C=12.500000,D=hello