导航:首页 > 源码编译 > pg类型转换为数组源码

pg类型转换为数组源码

发布时间:2022-12-25 10:23:52

A. PG字符串操作

1、查看是否包含子串

2、字符串切割为数组

3、替换子串

4、截取子串

4、拼接字符串

B. C语言里 灰度图像怎么转换为二维数组

1、步骤大概这样
第一步:读取图像数据到内存
第二步:读取文件头
第三步:读取信息头
第四步:读取图像矩阵到二维数组
2、例程:

FileName=fileDlg.GetFileName();
FILE*fp=fopen(FileName,"rb");//二进制读方式打开指定的图像文件
fread(&FileHead,sizeof(BITMAPFILEHEADER),1,fp);//读取文件头,文件指针自动后移
fread(&InfoHead,sizeof(BITMAPINFOHEADER),1,fp);//读取信息头,文件指针自动后移
//获取图像宽、高、每像素所占位数等信息
bmpWidth=InfoHead.biWidth;
bmpHeight=InfoHead.biHeight;
//下面完成图像数据向内存数组的存储
ImageData=newunsignedchar*[bmpHeight];
if(InfoHead.biBitCount==24)
{
for(inti=0;i<bmpHeight;i++)
{
ImageData[i]=newunsignedchar[(bmpWidth*3+3)/4*4];
}
for(intk=0;k<bmpHeight;k++)
{
for(intj=0;j<(bmpWidth*3+3)/4*4;j++)
{
fread(&ImageData[k][j],1,1,fp);//上面完成动态二维数组的申请,这里实际读取图像数据
}
}
fclose(fp);//关闭文件

C. 内存管理技术四:xvisor实现源码分析2

Guest在发生异常的时候,会触发vm_exit从guest切换到host,xvisor作为当前的host触发中断,通过stvec寄存器,调用在 xvisor/arch/riscv/cpu/generic/cpu_entry.S 中定义的 _handle_hyp_exception 异常处理函数。
HANDLE_EXCEPTION 定义的 do_handle_exception 是在 arch_cpu_irq_setup 中将其地址写入到了CSR_STVEC寄存器中,stvec寄存器是用来保存处理中断函数地址的寄存器。 arch_cpu_irq_setup 函数可以追溯到 vmm_entry 中的 cpu_init 。

_handle_hyp_exception 首先对通用寄存器和虚拟化h寄存器的内容进行保存然后跳转到HANDLE_EXCEPTION, HANDLE_EXCEPTION 会调用 do_handle_exception 。 xvisor/arch/riscv/cpu/generic/cpu_exception.c 中do_handle_exception函数调用对应的中断或者异常,此处进入 do_handle_trap ,根据寄存器cause的值,判断是哪一种trap,此处我们要处理的page fault将会根据case中跳转到 cpu_vcpu_page_fault 中。

cpu_vcpu_page_fault 中首先会获取fault_addr,此处的fault_addr可以理解为guest的gpa。接着根据这个地址先去guest的region_list中判断当前的fault_addr是否在region中,如果识别到当前的地址指向的是一个 VMM_REGION_VIRTUAL 的虚拟设备,则直接通过 cpu_vcpu_emulate_load/store 进行模拟的读写操作。如果当前地址不是虚拟的设备,则通过map的方式寻找到gpa对应hpa。接下来我们将详细讲述以上描述的过程。

首先要理解,两阶段地址转换是不会触发page fault的,guest在正常运行的过程中,首先会在vsatp寄存器中获取页表的地址,然后再hgatp寄存器中获取第二阶段页表的地址,通过nest的方式完成寻址。发生page fault是因为访问硬件设备,或者申请的虚拟地址并没有真正分配内存的时候。 cpu_vcpu_page_fault 函数处理的流程就是根据fault_addr,也就是guest的gpa来判断是否能够找到对应的region,且这个region还是一个virtual的device,这样的话就可以直接调用调用 cpu_vcpu_emulate_load/stroe 去完成。
vmm_guest_find_region 中首先会根据reg的flag判断设备到底是属IO/Memory,在xvisor中将所有的设备都定义为了memory形式。然后根据flag信息获得设备树的根节点,因为IO/Memory是不同的设备树,拥有不同的根节点。在获取设备树的根节点之后,判断传入的fault_addr也就是gpa在哪个节点。如此就通过树的方式找到是否找到了gpa对应的region。

vmm_guest_find_region 函数会根据传入的gpa和flag信息找到对应的region,如果可以找到,则表明当前的gpa访问的是一个虚拟的设备。就可以直接进行模拟的读写操作。在 vmm_devemu_emulate_read 的模拟读的操作中,真正执行读操作的是 devemu_doread ,传入的参数就有 reg->devemu_priv ,也就是在 region_add 中给 virtual device 传入的模拟设备的结构体变量, devemu_priv 是一个指针,指向的emulator设备。有了定义的模拟的设备的结构体,就可以去对应模拟设备中执行操作,比如读取rtc的时间。Guest读取rtc的操作是在guest启动的时候从vmm中获取一个起始时间,加上系统运行的时间就获得了实时的时间。

如果传入的gpa访问的不是虚拟的设备,那么就需要找到gpa对应的hpa。这个操作就是由 cpu_vcpu_stage2_map 来完成的。

cpu_vcpu_stage2_map中首先定义了一个页 struct mmu_page pg; 的结构体,用来保存gpa,hpa,size和flag等信息。

定义一个地址将gpa的后12位清零,因为gpa->hpa的转换后12位为页内偏移,是不会变化的,所以想要找到gpa对应的hpa只要找到gpa的页对应的hpa对应的物理页即可。
inaddr = fault_addr & PGTBL_L0_MAP_MASK;
在获得gpa对应的页之后,尝试将页去guest对应的设备树中寻找对应的hpa页。 vmm_guest_physical_map 函数首先是继续将获得页作为gpa去 vmm_guest_find_region 。

如果转化成页的gpa还没有找到对应的region,则表明 cpu_vcpu_stage2_map 阶段失败,将直接返回并打印出错误的gpa地址。

在guest的region_list中找到gpa页对应的region之后,就可以去region中去找对应的hpa了, vmm_guest_find_mapping 用来完成这个步骤。 vmm_guest_find_mapping-> mapping_find 根据gpa的地址寻找到mapping数组中对应的i。在region_add章节中可以知道,mapping是一个数组,比如mem0代表guest内存的部分,就有一百多个数组。
map = mapping_find(guest, reg, &i, gphys_addr);
在获得数组的对应的i之后,就可以根据region的起始地址加上i对应的偏移量之后,得到region中对应的gpa。Hphys是mapping数组的起始hpa,加上偏移量就得到了数组中对应的hpa的地址。将这个得到的hphys传给指针hphys_addr指针指向的地址。

到这里 vmm_guest_physical_map 中传入的参数hphys_addr就已经获取到了hpa的对应地址,此时要将对应的gpa,hpa,size等信息填充到mmu_page这个结构体中。

(TODO:在cpu_vcpu_stage2_map中对RAM/ROM和64位的情况下有另外的操作,比如对于64位的情况不再是对页进行映射,而是对vpn[3]作为gpa进行地址进行映射,需要进行分析这么做的原因是什么)

在拥有了gpa,hpa,size和flag等信息之后,需要将该部分内容填充到页表中。虽然页表的寻址是通过mmu,tlb等硬件完成的,但是页表项pte等内容是由软件来完成的。 arch_mmu_pgflags_set 根据获得region flag来填充pg结构体中flag的内容。注意在xvisor中,MMU_STAGE2是用来描述gpa->hpa的,但是MMU_STAGE1并不是用来描述guest在第一阶段的地址转换,而是xvisor自身的mmu转换,这个和文档中的内容有所不同。
arch_mmu_pgflags_set(&pg.flags, MMU_STAGE2, pg_reg_flags);
接着根据pg结构体的内容来填充stage2的页表内容。 riscv_guest_priv(vcpu->guest)->pgtbl 是从guest结构体中获得arch_priv指针指向的riscv_guest_priv结构体,并获得pgtbl页表的指针。页表结构体中用来存放虚拟地址,页的地址,pte页表项的内容信息。

mmu_map_page首先根据sz的判断,找到页表的对应的最后一级页表,此处采用的是递归的方式。因为我们知道页表指向的最后一级页表的PPN就是对应的物理地址,所以此处要填充的一定是最后一级页表中PPN的地址。mmu_pgtbl_get_child顾名思义,获取下一级页表返回一个页表结构体给child。

mmu_pgtbl_get_child 中将gpa对应的vpn[i]中的内容取出,变成了pte数组中的index。Pte指向的是上一级页表中的pte页表的pte数组首地址,pte_val就是数组中对应的pte的值。Pte_val本身也是一个数组,即页表项,由PPN和flag组成。

arch_mmu_pte_is_valid 用来判断pte的有效位是不是为1,如果为1就可以将页表项中的PPN通过偏移转换成地址赋给tbl_pa。 mmu_pgtbl_find ->mmu_pgtbl_nonpool_find ,去页表池中根据地址找到空闲的页表返回给child并且对child页表结构体进行初始化 mmu_pgtbl_alloc 。
找到需要填充的页表,并获得结构体之后,需要对虚拟地址对应的pte页表项内容进行填充,依然是根据虚拟地址找到对应的index,和pte数组的起始地址。
index = arch_mmu_level_index(pg->ia, pgtbl->stage, pgtbl->level); pte = (arch_pte_t *)pgtbl->tbl_va;
根据pg结构体中的内容填充pgtbl中pte页表项的内容。 arch_mmu_pte_set(&pte[index], pgtbl->stage, pgtbl->level, pg->oa, &pg->flags);
arch_mmu_pte_set 传入的参数arch_pte_t *pte就是&pte[index],是vpn[]对应的pte,pte本身也是一个数组,首先将pa也就是pg->oa,是region中找到的hpa填充到pte对应的PPN中。

再来回顾一下sv32中pte页表项的内容,注意虽然PPN划分成了PPN[0]和PPN[1],但这两个在使用的时候是作为一个整体的。在经历过 arch_mmu_pte_set 后,gpa->hpa第二阶段页表中vpn[]对应的页表项的内容已经根据region寻找到了对应hpa并填充在对应的pte页表项pte中。这样硬件mmu就可以从多级页表的结构中寻找到gpa对应的hpa。多级页表的填充是同过递归的方式来实现的。

D. pg库substring数组用法

1) start_position==0时,子串的起始位置为1,即从第一个字符开始;
2) start_position<0时,字串的起始位置从字符串尾部开始后推。
3) length参数可以缺省。

E. java怎么处理postgresql的存储函数返回的数组

postgreSQL的JDBC驱动是支持数组返回的,数组对应的类型为org.postgresql.jdbc4.Jdbc4Array(我用的是jdbc4).

一个示例, 函数如下:

createorreplacefunctionfn_rtbAry()
returnsinteger[]
as$fn_rtbAry$
begin
return'{10,20,30}'::integer[];
end;
$fn_rtbAry$languageplpgsql;

Java中获得返回的数组, 要引入java.lang.*,java.sql.*,java.util.*,org.postgresql.jdbc4.*:

Connectionconn=null;
Statementcmd=null;
ResultSetrs=null;
Jdbc4Arrayobj=null;
Integer[]dataAry=null;
//...连接,查询创建以及初始化代码省略
rs=cmd.executeQuery("selectfn_rtbAry()asv");
//循环获得数据
while(rs.next()){
obj=(Jdbc4Array)rs.getObject(1);
dataAry=(Integer[])obj.getArray();//这里获得函数返回的数组,并转换成Integer数组
//其他代码省略
}
//释放对象代码省略

F. postgresql中如何将类型转换成numeric

select
24::numeric;

select '-20'::numeric;

G. Python中字符串与数组的转换方法

Python实现字符串与数组相互转换功能,具体如下:


1、字符串转数组:

H. postgresql里边的数组怎么操作

1. 数组可以作为字段类型

PostgreSQL中数据是一种基本的数据类型,可以作为字段的类型定义。例如,

CREATETABLEads.tb_mo_item
(
mo_keyintegerNOTNULL,
input_flowinteger[]NOTNULLDEFAULTARRAY[]::integer[]
);

2. 可以用array[]来初始化一个数组

selectarray[1,3,4]::int[];

3. 操作数组有一系列函数, 可以实现数组比较,添加新元素,一般数组是否包含另一数组的判断,等等。具体参考PostgreSQL说明文档中函数和操作符中有关Array的部分。

操作符有: =, <>, <, >, >=, <=, @>, @<, &&, ||

函数有: array_append, array_cat, array_ndims, array_dims, array_fill, array_length, array_lower, array_remove, array_replace, array_to_string, array_upper, string_to_array, unnest等.

其中,常用的是: array_append, array_length, unnest

4. 使用数组下标获得数组的元素,下标是从1开始的

select(array[1,3,4]::int[])[2];

5. 可以用unnest将数组转换成一个结果集,个人觉得这个很有用处

selecta.afromunnest(array[1,3,4]::int[])a;

I. pgsql里边怎样把integer类型转换为date类型

可以转的,只要你清楚数据库存储时间的真正格式。
事实上是float的
一天分为24小时,而小数点前面的整数就是天数,把24小时作为1。也就是说
1.5的意思,实际上是1天12个小时。单位可能不一定对,大概就是这么个意思

以此类推,往后的小数点排列不用我说了吧?

如果不相信,可以试试这个select cast(getdate() as float)

J. pg数据库如何传一个数组对象急急急。。。

pg数据库是什么?在sql里,首先,传递数组,不如传递字符串,然后通过自定义function,来split 这个字符串。当然,如果你一定要传递数组,那也可以在sql中创建自定义类型。然后创建存储过程,将数组录入到datatable,之后传递给你的存储过程中的这个自定义类型。

阅读全文

与pg类型转换为数组源码相关的资料

热点内容
linux命令返回上级目录 浏览:893
移动花卡宝藏版为什么不能选免流app 浏览:255
速腾carplay怎么用安卓 浏览:13
红塔银行app怎么样 浏览:564
农行app怎么开网银 浏览:651
java迭代器遍历 浏览:303
闽政通无法请求服务器是什么 浏览:48
怎么做积木解压神器 浏览:205
王者荣耀解压玩具抽奖 浏览:49
12位是由啥加密的 浏览:870
程序员编迷你世界代码 浏览:897
php取现在时间 浏览:248
单片机高吸收 浏览:429
怎么区分五代头是不是加密喷头 浏览:246
hunt测试服务器是什么意思 浏览:510
2013程序员考试 浏览:641
毕业论文是pdf 浏览:736
服务器跑网心云划算吗 浏览:471
单片机定时器计数初值的计算公式 浏览:801
win7控制台命令 浏览:567