Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# SetFilePointer不会失败,但也不会移动指针_C#_C++_Winapi - Fatal编程技术网

C# SetFilePointer不会失败,但也不会移动指针

C# SetFilePointer不会失败,但也不会移动指针,c#,c++,winapi,C#,C++,Winapi,首先,如果我说了一些愚蠢的话,请原谅,我不是IT人员,而是电子工程师,但我被分配到了一些需要更多技能的工作 我需要在SD卡中写入和读取物理扇区。我已经用C++完成了,但是主要的应用程序是用C语言编写的,所以我认为编写第一个DLL是个好时机。 这是C++中用于编写扇区的代码。< /P> private: System::Void button4_Click(System::Object^ sender, System::EventArgs^ e) { HANDLE hFile = INVA

首先,如果我说了一些愚蠢的话,请原谅,我不是IT人员,而是电子工程师,但我被分配到了一些需要更多技能的工作

我需要在SD卡中写入和读取物理扇区。我已经用C++完成了,但是主要的应用程序是用C语言编写的,所以我认为编写第一个DLL是个好时机。

这是C++中用于编写扇区的代码。< /P>

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);
    }
然后我在C#项目中导入:

然后我调用函数:

int ResultEscribir = EscribeBloqueFisico(numeroDiscoFisico, BufferEscritura, 512, SectorEscribir * 512);
始终写入第一个扇区,无论“posicion_inicio”的值是多少(是起始偏移量,很抱歉使用了西班牙语标记),因此我更改了api中的写入函数,以返回dwPtr(SetFilePointer的结果),而不是写入的字节。这似乎总是零,这显然不是我想要的。但是找不到为什么第一个函数有效而dll调用无效

也许这是第一眼就应该看到的东西,但正如我所说,我是电子人,不习惯这种编程

其他功能(如读取磁盘几何图形或卷磁盘扩展数据块)也可以工作,我使用这些功能来确定哪个物理驱动器是给定的逻辑单元。正如我所说,写作和阅读都很好,只是我总是指向零区

提前谢谢。而且,这是我第一次在这里发帖。很多次(这就是为什么我选择这里问),但是如果我在发布问题时犯了一些错误,请指出它。

< P>一个C++中的长是32位。这使得它在C#中是一个int。在pinvoke声明中用int替换long


你应该得到Pinvokes的警告。如果关闭了警告,请确保重新启用该警告。很容易看出调试器中*posicion\u inicio*的值是错误的。确保启用非托管调试、项目+属性、调试选项卡。现在可以在C++代码中设置断点。这(在c中声明为int,在c++中是长的)解决了这个问题。还非常感谢您在非托管代码调试中提供的提示,我不知道该选项。现在它按预期工作。我想这会让我在切换语言时更加关注数据类型。再次感谢!请原谅我的英文:)编辑:不能投票的答案,好像我需要信誉15这样做。技术上的<代码>长< /C> >微软Visual C++ +是32位。IIRC,在Linux/G++上,它通常是64位的,就像在C#中一样。
[DllImport("AccesoBajoNivel.dll", CallingConvention = CallingConvention.Cdecl)]
static extern int EscribeBloqueFisico(char numeroDisco, byte[] buffer, long BytesQueEscribir, long posicion_inicio);
int ResultEscribir = EscribeBloqueFisico(numeroDiscoFisico, BufferEscritura, 512, SectorEscribir * 512);