随后使用LuaJIT的FFIMSDN's GetOpenFileName example。我已经试着让这个工作了两天,不仅对话框没有打开,而且它崩溃了整个事情。
当使用OllyDdb进行调试时,它会在comdlg32.dll的某个地方抛出一个丑陋的访问冲突。
这是概念的证明,只有基本的代码。如果我指定结构大小为零,则它退出没有问题,用GETLASTRORNOR()抛出87(ErrRoSimulyIdId参数)
所以我认为这个问题与struct或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()
最佳答案
这些C函数带一个指向结构的指针。正确的声明是:GetOpenFilenameA(OPENFILENAME *lpofn)
等。
关于c - 用LuaJIT调用标准打开对话框会导致访问冲突,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11846910/