C# 내에서 포인터 (C/C++ 스타일)에 메모리를 할당하는 올바른 방법에 대해 궁금합니다. 그런 다음 오랜 시간 동안 해당 메모리를 누르고 있습니다. 또한이 할당 된 메모리는 DeviceIoControl()에 대한 호출에 사용하기위한 것입니다. 이 클래스를 고려관리되는 개체에 대한 관리되지 않는 메모리 할당
이class Example {
const uint memCommit = 0x1000;
const uint pgReadWrite = 0x04;
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern IntPtr VirtualAlloc(IntPtr lpAddress, UIntPtr dwSize, uint flAllocationType, uint flProtect);
[StructLayout(LayoutKind.Sequential)]
struct AStruct {
uint val1;
uint val2;
uint val3;
}
private static unsafe AStruct* pStruct = (AStruct*)VirtualAlloc(IntPtr.Zero, (UIntPtr)(sizeof(AStruct)), memCommit, pgReadWrite).ToPointer();
public static unsafe void ReadFromDevice() {
// setup the structure for the IOCTL call
pStruct->val1 = 70; //
pStruct->val2 = 0;
pStruct->val3 = 0x0f;
// call P/Invoked DeviceIoControl() here with pStruct as both the in/out pointers
// check that all is well
}
}
이 모든 것은 바로 나에게 "느낌"하지 않지만, 내가 바로 공부를하지 않고 구현에 의문을 제기하지 않도록 년간 충분히 배웠다. 이것이 저를이 포럼에 데려 오는 것입니다. 나는 전에 보지 못한 행동을보고 있습니다.
디버거를 사용하여 포인터가 VirtualAlloc()에 대한 호출로 인스턴스화 된 지점에 중단 점을 배치합니다. 나에게 주어진 주소를 기록해 둡니다 (예 : 0x03bf78cc). 또한 위의 ReadFromDevice() 메서드를 호출하는 다른 함수에 중단 점이 있습니다. ReadFromDevice()를 통해 단계를 밟으면서 pStruct에는 프로그램이 처음 시작될 때 할당 된 주소와 다른 주소가 포함됩니다. pStruct의 값이 위의 번호에서 0x03cd9004로 변경되었습니다.
, 나는 이전에()는의 Kernal32 기능의 DeviceIoControl에 전화로 근무했습니다과 방법은 전화를 걸) DeviceIoControl을 (호출에 사용되는 데이터 구조에 고정 GCHandle의 인스턴스가 있었다 사용 밖으로 복사 적절한 데이터를 입력 한 다음 핸들을 비 웁니다. 이 접근법은 오류가 발생하기 쉽지 않으며 가능한 한 빨리 관리되지 않는 메모리를 할당하고 해제하는 모델과 일관성을 유지합니다.
앞에서 언급했듯이 내가 지금 사용하고있는 코드에서 사용 된 접근 방식은 "느끼기"쉽지 않지만 왜 그런지는 잘 모르겠습니다. 나는 "alloc 후에 c 날카로운 메모리 주소가 바뀌 었습니다."와 같은 것들에 대해서 구글 검색에서 아무것도 발견하지 못했습니다. 이 접근 방식을 변경해야합니까? (과거에는 고정 된 GC 핸들을 사용했습니다.) 위의 접근 방식이 효과가 있습니까? 그럼에도 불구하고, 포인터가 프로그램 시작 중에 하나의 메모리 주소를 말하고, 왜 ReadFromDevice() 호출이 실제로 수행 될 때 다른 포인터를 말합니까? 이 글을 쓰면서 나는 처음 생각한 것처럼 주소가 "이상하게"바뀌 었는지 궁금합니다. 그럼에도 불구하고, 나는 포인터의 사용에 대해 여전히 의문을 품고있다. 제발 조언.
덕분에,
이것은 내가이 작업을 수행하는 데 익숙한 방법입니다. 또는, 게시물에서 언급했듯이 고정 된 개체를 사용합니다. 기본적으로 사용 된 구현이 좋은지, 아니면 게시 한 내용으로 변경해야하는지 궁금합니다. 내가 사용하는 방법에 위험이 있는지 궁금하네요; 즉 정적 인 안전하지 않은 포인터가 있습니까? –