2016-08-23 128 views
0

我試過編譯一個使用win32api的windows可執行文件,但是我遇到了很多路障。用cygwin編譯winapi

首先要嘗試的是gcc -mno-cygwin [...]這導致gcc: error: unrecognized command line option '-mno-cygwin'這很奇怪,因爲man gcc|grep -e '-mno-cygwin'成功並且安裝了mingw。

無論我試圖包含哪些其他頭文件,我總是以不滿意的循環包含依賴項(a.h需要b.h需要a.h)結束。基於win32 api正確編譯可執行文件需要哪些頭文件?

頭文件我曾嘗試:

  • w32api/WINNT.H
  • w32api/DDK/NTDDK.H
  • w32api/WINDOWS.H
  • w32api/NTDEF.H

源代碼:

$ cat source.c 
#include <w32api/winnt.h> 
#include <w32api/ddk/ntddk.h> 

int main(int argc, char **argv) { 
    PHANDLE hProcess; 
    CLIENT_ID processId; 
    processId.UniqueProcess = (HANDLE) 1000; 
    processId.UniqueThread = 0; 

    NtOpenProcess(&hProcess, PROCESS_VM_READ|PROCESS_VM_WRITE, 0, &processId); 
    return 0; 
} 

$ gcc -o a.exe -I/usr/include/w32api -I/usr/include/w32api/ddk source.c 
In file included from memoryEdit.c:1:0: 
/usr/include/w32api/winnt.h:291:11: error: unknown type name 'CONST' 
    typedef CONST WCHAR *LPCWCH,*PCWCH; 
     ^
[...] 

$ gcc --version 
gcc (GCC) 5.4.0 
$ uname -a 
CYGWIN_NT-6.1 HOST_NAME 2.5.2(0.297/5/3) 2016-06-23 14:29 x86_64 Cygwin 
+0

*「Windows.h」*爲標準Windows應用程序。但是,[NtOpenProcess](https://msdn.microsoft.com/en-us/library/windows/hardware/ff567022.aspx)不是Windows API的一部分。你必須包含* Ntddk.h *或* Ntifs.h *,並解決其餘問題。任何原因您沒有像其他人一樣使用Windows API調用[OpenProcess](https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320.aspx)? – IInspectable

+0

@IInspectable既然'Ntifs.h'不能在我的系統上的任何地方找到我會假設你的意思是'ddk/ntifs.h',無論哪種方式導致錯誤'/ usr/x86_64-w64- = mingw32/sys-root/mingw/include/ddk/Ntifs.h:32:19:致命錯誤:ntddk.h:沒有這樣的文件或目錄,這只是我的原始問題。至於使用'NtOpenProcess'我無所謂,我只是複製並粘貼了一個hello世界風格的示例程序,並期望它至少可以編譯。 –

+0

@IInspectable我在gcc命令中加入了'-I/usr/x86_64-w64-mingw32/sys-root/mingw/include/ddk',它能夠找到'ddk/ntifs.h',錯誤'/usr/x86_64-w64-mingw32/sys-root/mingw/include/ddk/wdm.h:376:1:錯誤:'Windows.h'中'_InterlockedAdd64'的重定義包括但如果我刪除那麼我剩下'錯誤:未知類型名'BYTE''這只是我的原始問題。 –

回答

0

gcc -mno-cygwin已從多年前刪除。

如果你想編譯一個windows程序,你需要使用不是gcc編譯器,那就是cygwin到cygwin,但是交叉編譯器cygwin到windows。 有2包變種取決於弓:

mingw64-i686的-GCC
mingw64-x86_64的-GCC

+0

這回答問題的一半謝謝,所以我會問另一個更具體的問題。 –

0

我沒有煩惱剛纔在Eclipse中/ GCC彙編。這是我的測試文件:

/* 

============================================================================ 
Name  : win32gcctest.c 
Author  : Clark Thomborson 
Version  : 1.0 
Copyright : Copyleft 
Description : Testing winapi synchronous file access within Cygwin 
============================================================================ 
*/ 

#include <stdio.h> 
#include <windows.h> 
#include <stdlib.h> 
#include <fileapi.h> 

void my_write(char* fname) { 
    HANDLE hFile; 
    char DataBuffer[] = "This is some test data to write to the file."; 
    DWORD dwBytesToWrite = (DWORD) strlen(DataBuffer); 
    DWORD dwBytesWritten = 0; 
    BOOL bErrorFlag = FALSE; 

    hFile = CreateFile(fname,  // name of the write 
      GENERIC_WRITE,   // open for writing 
      0,      // do not share 
      NULL,     // default security 
      CREATE_ALWAYS,   // overwrite any existing file 
      FILE_ATTRIBUTE_NORMAL, // normal file 
      NULL);     // no attr. template 

    if (hFile == INVALID_HANDLE_VALUE) { 
     DWORD last_err = GetLastError(); 
     printf("Error code %d: unable to open file \"%s\" for write.\n", last_err, fname); 
     exit(last_err); 
    } 

    printf("Writing %d bytes to %s.\n", dwBytesToWrite, fname); 

    bErrorFlag = WriteFile(hFile, 
      DataBuffer,  // start of data to write 
      dwBytesToWrite, // number of bytes to write 
      &dwBytesWritten, // number of bytes that were written 
      NULL);   // no overlapped structure 

    if (FALSE == bErrorFlag) { 
     DWORD last_err = GetLastError(); 
     printf("Error code %d: unable to write to file \"%s\".\n", last_err, fname); 
     exit(GetLastError()); 
     exit(last_err); 
    } else { 
     if (dwBytesWritten != dwBytesToWrite) { 
      // This is an error because a synchronous write that results in 
      // success (WriteFile returns TRUE) should write all data as 
      // requested. This would not necessarily be the case for 
      // asynchronous writes. 
      printf("Error: dwBytesWritten != dwBytesToWrite\n"); 
      exit(EXIT_FAILURE); 
     } else { 
      printf("Wrote %d bytes to %s successfully.\n", dwBytesWritten, fname); 
     } 
    } 

    CloseHandle(hFile); 
} 

HANDLE my_open_for_read(char* fname) { 
    HANDLE hFile; 

    hFile = CreateFile(
     fname, 
     GENERIC_READ, 
     FILE_SHARE_DELETE, // another process may delete this file while this handle is open 
     NULL, // no security attributes 
     OPEN_EXISTING, // returns error if file not found 
     FILE_ATTRIBUTE_NORMAL, // no special attributes, so can't do async IO 
     NULL // no attributes will be copied from another file 
     ); 
    if (hFile == INVALID_HANDLE_VALUE) { 
     DWORD last_err = GetLastError(); 
     printf("Error code %d: unable to open file \"%s\" for read.\n", last_err, fname); 
     exit(last_err); 
    } 

    return hFile; 
} 

ssize_t my_read(HANDLE hFile, void *buffer, size_t bytes_to_read) { 

    DWORD bytes_read; 

    if (ReadFile(hFile, buffer, bytes_to_read, &bytes_read, NULL)) { 
     return (ssize_t) bytes_read; 
    } else { 
     DWORD last_err = GetLastError(); 
     printf("Error code %d: unable to read file.\n", last_err); 
     exit(last_err); 
    } 
} 

int main(void) { 
    char fname[32] = "test.txt"; 

    my_write(fname); 

    printf("Reading %s.\n", fname); 

    char buff[1024]; 
    HANDLE hFile = my_open_for_read(fname); 
    ssize_t nc = my_read(hFile, buff, 1023); // allow room for terminating byte 
    if(nc >= 0) { 
     buff[nc] = 0; // terminate string 
     printf("Read %d characters: %s", (int) nc, buff); 
     return EXIT_SUCCESS; 
    } else { // buggy my_read() 
     printf("Error %d", (int) nc); 
     return nc; 
    } 
}