2012-08-07 67 views
1

跟隨MSDN's GetOpenFileName example使用LuaJIT的FFI。我一直試圖讓這個工作兩天,不僅對話框不打開,而且它崩潰了整個事情。使用LuaJIT調用標準打開對話框會導致訪問衝突

當使用OllyDdb進行調試時,它會在comdlg32.dll的某個地方拋出一個醜陋的訪問衝突。

下面是隻有基本代碼的概念驗證。如果我指定的結構尺寸是零退出沒有問題,與GetLastError函數()扔(ERROR_INVALID_PARAMETER)

所以我想這個問題是結構或FFI有關。

如果有人能夠在這裏擺脫一些光......感謝。

ffi = require"ffi" 
bit = require"bit" 

collectgarbage("stop") 

ffi.cdef[[ 
    static const int OFN_FILEMUSTEXIST    = 0x1000; 
    static const int OFN_NOCHANGEDIR    = 8; 
    static const int OFN_PATHMUSTEXIST    = 0x800; 

    typedef bool BOOL; 
    typedef char CHAR; 

    typedef unsigned short WORD; 
    typedef unsigned long DWORD; 

    typedef void *PVOID; 
    typedef void *LPVOID; 
    typedef void *LPOFNHOOKPROC; 

    typedef unsigned long HANDLE; 
    typedef HANDLE HWND; 
    typedef HANDLE HINSTANCE; 

    typedef const char *LPCSTR; 
    typedef const char *LPCTSTR; 

    typedef char *LPSTR; 
    typedef char *LPTSTR; 

    typedef unsigned long LPARAM; 

    typedef struct { 
    DWORD   lStructSize; 
    HWND   hwndOwner; 
    HINSTANCE  hInstance; 
    LPCTSTR  lpstrFilter; 
    LPTSTR  lpstrCustomFilter; 
    DWORD   nMaxCustFilter; 
    DWORD   nFilterIndex; 
    LPTSTR  lpstrFile; 
    DWORD   nMaxFile; 
    LPTSTR  lpstrFileTitle; 
    DWORD   nMaxFileTitle; 
    LPCTSTR  lpstrInitialDir; 
    LPCTSTR  lpstrTitle; 
    DWORD   flags; 
    WORD   nFileOffset; 
    WORD   nFileExtension; 
    LPCTSTR  lpstrDefExt; 
    LPARAM  lCustData; 
    LPOFNHOOKPROC lpfnHook; 
    LPCTSTR  lpTemplateName; 

    LPVOID  pvReserved; 
    DWORD   dwReserved; 
    DWORD   flagsEx; 

    }OPENFILENAME; 

    BOOL GetSaveFileNameA(OPENFILENAME lpofn); 
    BOOL GetOpenFileNameA(OPENFILENAME lpofn); 
]] 
com=ffi.load("comdlg32") 

ffi.cdef[[ 
    DWORD GetLastError(void); 
]] 
krnl=ffi.load("kernel32") 

function OpenDialog() 
    Ofn=ffi.new("OPENFILENAME") 
    ffi.fill(Ofn,ffi.sizeof(Ofn)) --zero fill the structure 

    local szFile  = ffi.new("char[260]","\0") 
    local hwnd   = ffi.new("HWND",0) 

    Ofn.lStructSize  = ffi.sizeof(Ofn) 
    Ofn.hwndOwner  = hwnd 

    Ofn.lpstrFile  = szFile 
    Ofn.nMaxFile  = ffi.sizeof(szFile) 

    Ofn.lpstrFilter  = "All\0*.*\0Text\0*.TXT\0" 
    Ofn.nFilterIndex = 1 

    Ofn.lpstrFileTitle = nil 
    Ofn.nMaxFileTitle = 0 

    Ofn.lpstrInitialDir = nil 
    Ofn.flags   = bit.bor(com.OFN_PATHMUSTEXIST, com.OFN_FILEMUSTEXIST, com.OFN_NOCHANGEDIR) 

    print("displaying...") 

    if com.GetOpenFileNameA(Ofn) then --luajit converts bool automatically 
    print("file->",ffi.string(Ofn.lpstrFile, Ofn.nMaxFile)) 
    end 

    print("lasterror->",krnl.GetLastError()) 
end 

OpenDialog() 

回答

3

這些C函數帶有一個指向結構體的指針。正確的聲明是:GetOpenFilenameA(OPENFILENAME *lpofn)

+0

哦,這是尷尬的,謝謝你,工作完美無瑕。迷失在翻譯:) – Swyter 2012-08-08 09:30:40

相關問題