원시 바이너리 구조를 D의 파일에 작성합니까?
일부 .NET에서 정의 된 여러 이진 레코드가 포함 된 이진 파일을 만들려고합니다 struct
. 그러나 나는 그것을하는 방법을 찾지 못하는 것 같습니다. 다른 예를 살펴보면 string
문제없이 s 를 작성할 수 있었지만 struct
. 에서 C
와 같이 작성하고 fwrite(3)
싶지만 D
버전 2 에서는 작성하고 싶습니다 .
지금까지 시도한 내용은 다음과 같습니다.
- 사용하는
stream.write(tr)
- 사람이 읽을 수 / 디버그 표현을 쓴다 - 사용
stream.rawWrite(tr)
-이것은 내가 필요한 것처럼 들리지만 다음으로 컴파일하지 못했습니다.
오류 : std.stdio.File.rawWrite 템플릿은 인수 유형! () (TitleRecord)에서 함수를 추론 할 수 없습니다. 후보는 다음과 같습니다.
/usr/lib/ldc/x86_64-linux-gnu/include/d/std/stdio.d(1132) : std.stdio.File.rawWrite (T) (T [] 버퍼에서)
rawWrite
위와 같이 시도 하지만 데이터를 다양한 것으로 캐스팅하면 컴파일되지 않습니다.- 심지어 다시 얻으려고 노력
C
으로fwrite
하지만, 파일 기술자 I의 필요성을 얻기 위해 깊은 충분히 얻을 수 없습니다.
문서 를 읽는 것은 그다지 도움이되지 않았습니다 (문자열 쓰기는 저에게도 효과가 있지만 작성하지는 않습니다 struct
). 나는 그것을 할 수있는 간단한 방법이있을 것이라고 확신한다. 그러나 나는 그것을 찾을 수 없다 .... 다른 SO 질문 은 나를 돕지 않았다 . 나 D 1.0
, 그것은 함께 달성되었을 수도 stream.writeExact(&tr, tr.sizeof)
있지만 더 이상 선택 사항이 아닙니다.
import std.stdio;
struct TitleRecord {
short id;
char[49] text;
};
TitleRecord tr;
void main()
{
auto stream = File("filename.dat","wb+");
tr.id = 1234;
tr.text = "hello world";
writeln(tr);
//stream.write(tr);
//stream.rawWrite(tr);
//stream.rawWrite(cast(ubyte[52]) tr);
//stream.rawWrite(cast(ubyte[]) tr);
//fwrite(&tr, 4, 1, stream);
}
답변
이를 위해 그 오류는 구조체가 아닌 배열이 필요하다는 것을 의미합니다. 따라서이를 수행하는 한 가지 쉬운 방법은 포인터를 슬라이스하여 rawWrite에 제공하는 것입니다.
stream.rawWrite((&tr)[0 .. 1]);
는 (&tr)
따라서 포인터로 구조체를 변환, 주소를 가져옵니다. 그런 다음 [0 .. 1]
수단은 처음부터 하나의 요소 만 잡아서 조각을 얻습니다.
따라서 이제 T[]
rawWrite가 하나의 요소를 포함하여 처리 할 수 있습니다.
@safe
주석 을 사용하는 경우 통과하지 못할 경우 표시해야합니다 @trusted
. 또한 물론 string
C 경험에서 확실히 알고 있듯이 구조체 내부의 모든 참조 (포함 )는 데이터 대신 이진 포인터로 작성됩니다. 그러나 당신이 거기에서 보여준 경우 당신은 괜찮습니다.
편집 : BTW fwrite
원하는 경우 C에서 동일한 코드를 복사 / 붙여 넣기하여 사용할 수도 있습니다 ( foo.sizeof
대신 대신 sizeof foo
). D File
는 C를 둘러싼 작은 래퍼 FILE*
이며 원래 FILE *을 다시 가져 와서 다른 함수로 전달할 수 있습니다.stream.getFP()
http://dpldocs.info/experimental-docs/std.stdio.File.getFP.html )
rawWrite
배열이 필요하지만 많은 해결 방법이 있습니다.
하나는 단일 요소 배열을 만드는 것입니다.
file.rawWrite([myStruct]);
또 다른 하나는 구조체를 배열로 캐스팅하는 것입니다. 내 라이브러리 인 bitleveld에는 reinterpretAsArray
. 이것은 또한 상기 구조체의 체크섬을 쉽게 생성 할 수 있도록합니다.
가끔이 방법을 사용하는 정렬에 문제가 발생 했으므로 조심하십시오. align
구조체 의 속성을 변경하여 수정할 수 있습니다 .