首先,請原諒我,如果我說什麼傻,我也不IT的傢伙,但電子工程師,但我被分配到的東西,需要更多的技能,我做的。SetFilePointer不會失敗,也不會移動指針
我需要編寫,並在讀取SD卡的物理扇區。我已經用C++完成了它,但主要的應用程序是用C#編寫的,所以我認爲這是編寫我的第一個dll的好時機。
這裏是C++的工作寫扇區的代碼。
private: System::Void button4_Click(System::Object^ sender, System::EventArgs^ e) {
HANDLE hFile = INVALID_HANDLE_VALUE;
BOOL fSuccess = FALSE;
DWORD dwBytesWritten = 0;
unsigned char chBuffer[SIZE];
long SectorActual = 39;
long PosicionInicio = SectorActual * 512;
for (int i=0; i<SIZE; i++) // Garbage values to be written
{
chBuffer[i]= i % 16;
if((i/16)%2==0)
{
chBuffer[i]= 15 - chBuffer[i];
}
}
hFile = CreateFileA("\\\\.\\PhysicalDrive5",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
textBox1->Text += "Could not open file (error " + GetLastError() + ") \r\n";
return;
}
DWORD dwPtr = SetFilePointer(hFile,
PosicionInicio,
NULL,
FILE_BEGIN);
if (dwPtr == INVALID_SET_FILE_POINTER) // Test for failure
{
textBox1->Text += "Error moving pointer (error " + GetLastError() + ") \r\n";
return; // Deal with failure
} // End of error handler
fSuccess = WriteFile(hFile, chBuffer, TAMANYO_SECTOR, &dwBytesWritten, NULL);
if (!fSuccess)
{
textBox1->Text += "WriteFile failed\r\n";
}
else
{
textBox1->Text += "WriteFile wrote " + dwBytesWritten.ToString() + " bytes\r\n";
}
CloseHandle(hFile);
}
然後我做了DLL。功能是這樣的:
[DllImport("AccesoBajoNivel.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int EscribeBloqueFisico(char numeroDisco, byte[] buffer, long BytesQueEscribir, long posicion_inicio);
然後我調用該函數::
int AccesoBajoNivel::EscribeBloqueFisico(char numeroDisco, unsigned char * buffer, long BytesQueEscribir, long posicion_inicio)
{
HANDLE hFile = INVALID_HANDLE_VALUE;
BOOL fSuccess = FALSE;
DWORD dwBytesWritten = 0;
char ArrayDeChars[] = "\\\\.\\PhysicalDrive5";
ArrayDeChars[17] = numeroDisco;
LPCSTR pathAlDisco = ArrayDeChars;
hFile = CreateFileA(pathAlDisco,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
//printf("Could not open file (error %d)\n", GetLastError());
CloseHandle(hFile);
return -1;
}
DWORD dwPtr = SetFilePointer(hFile,
posicion_inicio,
NULL,
FILE_BEGIN);
if (dwPtr == INVALID_SET_FILE_POINTER) // Test for failure
{
CloseHandle(hFile);
return -2; // Deal with failure
} // End of error handler
fSuccess = WriteFile(hFile, buffer, BytesQueEscribir, &dwBytesWritten, NULL);
if (!fSuccess)
{
CloseHandle(hFile);
return -3;
}
else
{
CloseHandle(hFile);
//return dwBytesWritten;
return dwPtr;
}
CloseHandle(hFile);
}
然後我在C#項目進口
int ResultEscribir = EscribeBloqueFisico(numeroDiscoFisico, BufferEscritura, 512, SectorEscribir * 512);
始終寫入第一個扇區,無論價值「posicion_inicio」(起始偏移量,對西班牙語標記抱歉)所以這就是爲什麼我改變了api中的寫入函數以返回dwPtr(SetFilePointer的結果)而不是寫入的字節。這似乎總是零,這顯然不是我想要的。但無法找到爲什麼第一個功能的作品和DLL呼叫不。
也許是應該第一眼看到的,但正如我所說,我是電子人,不習慣這種編程...
其他功能(如在閱讀DISK_GEOMETRY或VOLUME_DISK_EXTENTS)的工作,我用它來確定哪個物理驅動器是給定的邏輯單元。正如我說的,也寫入和讀出工作做好了,這只是我總是指着部門零...提前
感謝。另外,這是我第一次在這裏發帖。重複多次(這就是爲什麼我選擇在這裏問),但如果我在發佈問題時犯了一些錯誤,請指出。
非常感謝。那(在c#中聲明爲int是什麼在C++中長)解決了這個問題。也非常感謝你在非託管代碼調試中的提示,不知道這個選項。現在它按預期工作。我想這應該讓我在切換語言時更注重數據類型。再次感謝!請原諒我的英語:)編輯:不能投票答案,因爲似乎我需要聲望15這樣做。 – JeToMad
從技術上講,Microsoft Visual C++ **中的「long」是32位。 IIRC,在Linux/G ++上它通常是64位,就像在C#中一樣。 – MSalters