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()
哦,這是尷尬的,謝謝你,工作完美無瑕。迷失在翻譯:) – Swyter 2012-08-08 09:30:40