我一直在尝试使用c ++从头开始创建一个midi文件。我正在将不同的块(和部分块)分成不同的字符数组。
我的代码:
#include <iostream>
#include <fstream>
#include <cstring>
int main(int, char* []) {
std::ofstream MIDIfile ("example.mid")
char header[] = { /* hex data */ };
char track_header[] = { /* hex data */ };
char track_data[] = { /* hex data */ };
MIDIfile << strcat(header, strcat(track_header, track_data));
MIDIfile.close();
return 0;
}
我唯一的问题是,在写入文件时,仅写入了81个字节中的8个字节。是否有一个原因?我在做错什么吗?
致谢,shadowstalker75
答案 0 :(得分:1)
您将必须了解testMemory
的用途。这条线永远行不通。实际上,更好的是,永远不要使用#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Louis Jenkins");
MODULE_DESCRIPTION("Persistent Memory Analysis Tool - Kernel Module");
MODULE_VERSION("0.1");
static uint64_t *testMemory;
static uint64_t *readMemory;
static struct resource res[] = ;
static struct platform_device *pdev;
static int __init dummymodule_init(void){
void *addr;
int i;
int ret;
size_t size;
dma_addr_t dma_handle;
// Allocate memory...
testMemory = kvzalloc(sizeof(*testMemory), GFP_KERNEL);
readMemory = kvzalloc(sizeof(*readMemory), GFP_KERNEL);
// Give testMemory a deterministic value
*testMemory = 1;
// Initialize resource to point to the readMemory (so that it will do a DMA memory-to-memory
// transfer from testMemory into readMemory...
res[0] = (struct resource) {
.start = virt_to_phys(readMemory),
.end = virt_to_phys(readMemory) + sizeof(*readMemory),
.flags = IORESOURCE_MEM,
.name = "readMemory"
};
// Some debug information...
printk(KERN_INFO ".start = %u, .end = %u\n", res[0].start, res[0].end);
// Allocate platform device
pdev = platform_device_alloc("Non-Coherent DMA Memory Prodding Tool", 0);
// Ensure that it did not return NULL
printk(KERN_INFO "Allocated pdev: %x", pdev);
BUG_ON(pdev == NULL);
// Configure resources
pdev->num_resources = 1;
pdev->resource = res;
// Add device
ret = platform_device_add(pdev);
if (ret != 0) {
printk(KERN_ERR "Could not add device! error=%d", ret);
BUG();
}
// Perform DMA memory-to-memory of testMemory into (hopefully) readMemory
dma_handle = dma_map_single(&pdev->dev, testMemory, sizeof(*testMemory), DMA_TO_DEVICE);
BUG_ON(dma_mapping_error(&pdev->dev, dma_handle));
for(i = 0; i < 1000000; i++) {
// I don't know if DMA will be performed immediately, so I poll on it a bit...
if (readMemory == 0) {
__asm__ __volatile__ ("NOP");
} else {
break;
}
}
// Debug information... Prints out whether we read the value from CPU Cache or not
printk(KERN_INFO "testMemory = %d, readMemory = %d", *testMemory, *readMemory);
dma_unmap_single(&pdev->dev, dma_handle, size, DMA_TO_DEVICE);
return 0;
}
static void __exit dummymodule_exit(void){
kvfree(testMemory);
kvfree(readMemory);
platform_device_unregister(pdev);
}
module_init(dummymodule_init);
module_exit(dummymodule_exit);
。废话。
strcat()
您有十六进制数据的二进制缓冲区,只需使用strcat()
函数:
MIDIfile << strcat(header, strcat(track_header, track_data));
并一次写入一个缓冲区。
答案 1 :(得分:1)
formatted operator<<
function for char
arrays or pointers用于打印 空终止 字符串。如果您的“十六进制数据”包含任何零(二进制零,0
,而不是字符'0'
),那么它将用作终止符。
更不用说缓冲区溢出了,因为您将附加到固定大小的数组中,该数组专门针对初始化数据而设置。
解决方案是首先不要将任意二进制数据用作字符串(strcat
函数 希望数据为以空值结尾的字符串),而不能用作原始数据。其次,您需要使用the write
function写入任意数据。