c++内存与c#等价
C++ memcpy to c# equivalent
我实际上是一个java开发人员,但是对于一个休闲项目,我正在尝试将一个库从c++转换为c#。我有一点c++背景,但这段代码让我很困惑
long hfzWriteHeader(hfzFile* fs, hfzHeader& fh) {
// copy header into buffer
char HeaderBuf[28];
long HeaderBufPos = 0;
sprintf(HeaderBuf+HeaderBufPos, "HF2"); HeaderBufPos+=4;
hfzMemcpy(HeaderBuf+HeaderBufPos, &(fh.FileVersionNo), 2); HeaderBufPos+=2;
hfzMemcpy(HeaderBuf+HeaderBufPos, &(fh.nx), 4); HeaderBufPos+=4;
hfzMemcpy(HeaderBuf+HeaderBufPos, &(fh.ny), 4); HeaderBufPos+=4;
hfzMemcpy(HeaderBuf+HeaderBufPos, &(fh.TileSize), 2); HeaderBufPos+=2;
hfzMemcpy(HeaderBuf+HeaderBufPos, &(fh.Precis), 4); HeaderBufPos+=4;
hfzMemcpy(HeaderBuf+HeaderBufPos, &(fh.HorizScale), 4); HeaderBufPos+=4;
// put extended header into a buffer
char* pExtHeaderData = 0;
long rval = hfzHeader_EncodeExtHeaderBuf(fh, &pExtHeaderData);
if(rval<0) return rval;
// now write in header length of ext header
hfzMemcpy(HeaderBuf+HeaderBufPos, &(fh.ExtHeaderLength), 4);
HeaderBufPos+=4;
// swap byte order if required (files use little endian)
if(LIBHFZ_BYTEORDER_BIGENDIAN==hfzByteOrder) {
HeaderBufPos = 4; // skip "HF2 " string
hfzByteSwap(HeaderBuf+HeaderBufPos, 2); HeaderBufPos+=2; // FileVersionNo
hfzByteSwap(HeaderBuf+HeaderBufPos, 4); HeaderBufPos+=4; // nx
hfzByteSwap(HeaderBuf+HeaderBufPos, 4); HeaderBufPos+=4; // ny
hfzByteSwap(HeaderBuf+HeaderBufPos, 2); HeaderBufPos+=2; // TileSize
hfzByteSwap(HeaderBuf+HeaderBufPos, 4); HeaderBufPos+=4; // Precis
hfzByteSwap(HeaderBuf+HeaderBufPos, 4); HeaderBufPos+=4; // HorizScale
hfzByteSwap(HeaderBuf+HeaderBufPos, 4); HeaderBufPos+=4; // ExtHeaderLength
}
// write header
if(28!=hfzWrite(fs, HeaderBuf, 28))
return LIBHFZ_ERROR_WRITE_HEADER_FAILED;
// write extended header
if(pExtHeaderData) {
if(fh.ExtHeaderLength!=hfzWrite(fs, pExtHeaderData, fh.ExtHeaderLength)) {
hfzFree(pExtHeaderData);
return LIBHFZ_ERROR_WRITE_EXTHEAD_FAILED;
}
hfzFree(pExtHeaderData);
}
return LIBHFZ_STATUS_OK;
}
我相信它试图在内存中建立一个字符数组(字符串?),以便他可以稍后将其写入二进制文件。这是文件类型的头部分。在java中,我可能只会使用字符串构建器,然后追加。然而,我确实相信一些字节操作正在进行,字符串的每个部分都是相同的字节数,但我想知道fh。Nx是空的如果空的值是1,结果会是什么?是"1"还是"0001"?这就是我不明白的地方。
感谢任何对我C语言知识不足的帮助或启发
似乎把整个函数放在这里会更好,而不是它的一部分,因为稍后会发生一些与BIGENDIAN情况。很抱歉,在stackoverflow上正确使用格式是很麻烦的。
========= 初步的结果 ==============
所以我最终使用John Skeet的类来处理端序,并想出了这个…我只是想知道我是不是做错了。我是基于c++的方法结构重写的,但是很多方法都是低级别的,它们在更高级别的c#中是可用的……现在我记得为什么我选择Java而不是c了。我很快就被所有的指针和内存处理搞混了!
仅供参考,这是我试图编写和转换库的文件格式:http://www.bundysoft.com/docs/doku.php?id=l3dt:格式:规格:hf2
// copy header into buffer
MiscUtil.Conversion.EndianBitConverter endian = MiscUtil.Conversion.EndianBitConverter.Big;
if (BitConverter.IsLittleEndian)
{
endian = MiscUtil.Conversion.EndianBitConverter.Little;
}
MemoryStream buffer = new MemoryStream();
EndianBinaryWriter writer = new EndianBinaryWriter(endian, buffer);
writer.Write("HF2");
writer.Write(fh.FileVersionNo);
writer.Write(fh.nx);
writer.Write(fh.ny);
writer.Write(fh.TileSize);
writer.Write(fh.Precis);
writer.Write(fh.HorizScale);
这是对结构化数据执行一种二进制序列化。查看BinaryWriter以获得。net中的类似功能。这可以附加到任何流,但如果你想使用字节数组作为后备存储(如在C代码中),可以使用MemoryStream。
还要注意(正如另一个海报提到的),您可能必须注意尾端性和其他特定于平台的问题,至少假设您希望与C程序二进制兼容。在不知道原始程序使用的平台以及如何与之交互操作(如果有的话)的情况下,很难说得更多。例如,数据是否保存到您希望能够加载的文件中?
更新:
根据您的编辑,看起来原始代码是尾端感知的。你可以使用BitConverter。IsLittleEndian来检查你的平台的端进性,并在你的c#代码中对你的字节数组进行等效的交换调整。
如果你知道你在Windows上运行并且不想担心跨平台支持,你可以假设BinaryWriter是Little Endian(实际上,它可能在Mono中也是Little Endian,甚至在Big Endian平台上,但我不确定。)如果您希望安全起见,您可以查看Jon Skeet编写的一个实用程序类,它处理必要的转换。
取决于大小(短)和机器是大端还是小端。Sizeof (short)可能是2(但没有什么可以保证),给出:
- big-endian: 00 01 xx xx
- little-endian: 01 00 xx xx
其中xx是一些随机的垃圾。00表示值为0x00的字节;01是一个值为0x01的字节。
为什么代码复制四个字节是一个谜…
整个事情是可怕的:它导致特定于平台和(我相当确定,但不要引用我的话)未定义的行为。
更新:考虑到OP的更新(变量是长而不是短,以及处理端序的额外代码),我的最后一句话现在有点不合理了。
[DllImport("kernel32.dll")]
private static extern void RtlMoveMemory(IntPtr dest, IntPtr src, int byteCount);
这是一个与指针一起使用的真正的内存拷贝,并且应该在所有版本的Windows上工作。
- 将字符串存储在c++中的稳定内存中
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- Win32编译器选项和内存分配
- 当vector是tje全局变量时,c++中vector的内存管理
- 带内存和隔离功能的SQLite
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 迭代时从向量和内存中删除对象
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 为什么示例代码访问IUnknown中已删除的内存
- 如何在C++类内存结构中创建"spacer"?
- 从构造函数抛出异常时如何克服内存泄漏
- malloc() 可能出现内存泄漏
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- C#中等价的C++内存复制
- c#等价于c++的vector,具有连续内存
- 这些锁定的内存访问是等价的吗?
- c++内存与c#等价