1

LuaJITのFFIを使用して、MSDNのGetOpenFileNameの例に従いました。私はこれを2日間機能させようとしてきましたが、ダイアログが開かないだけでなく、全体がクラッシュします。

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()
4

1 に答える 1

4

これらの C 関数は、構造体へのポインターを取ります。正しい宣言は次のとおりですGetOpenFilenameA(OPENFILENAME *lpofn)

于 2012-08-07T21:06:44.550 に答える