使用LuaJIT的FFI跟随MSDN's GetOpenFileName example。我一直试图让这个工作两天,不仅对话框没有打开,而且它会使整个事情崩溃。
使用OllyDdb调试时,它会在 comdlg32.dll 中的某处抛出一个丑陋的访问冲突。
这是仅使用基本代码的概念证明。如果我指定结构大小为零,则退出时没有问题, GetLastError()抛出 87 (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()
答案 0 :(得分:4)
这些C函数采用指向结构的指针。正确的声明是:GetOpenFilenameA(OPENFILENAME *lpofn)
等。