在MinGW上使用libffi调用Windows API
Calling Windows API with libffi on MinGW
我正在尝试为我的新编程语言提供FFI支持,该语言是用c++和QT Creator使用MinGW工具链编写的。
为此,我使用了libffi的自定义版本:http://ftp.gnome.org/pub/GNOME/binaries/win32/dependencies/libffi-dev_3.0.6-1_win32.zip
我还尝试了另一个版本:http://pkgs.org/fedora-14/fedora-updates-i386/mingw32-libffi-3.0.9-1.fc14.noarch.rpm.html,在Linux上下载SRPM文件,提取它,并将所需的文件复制到Windows分区。
无论如何,我包含了所需的头文件,将导入库添加到项目中,并将.dll放在应用程序的。exe旁边,它编译并运行,成功调用MessageBeep()。接下来我尝试了MessageBoxA(),但它一直崩溃。调试器似乎没有提供多少有用的信息(编辑:除了对MessageBoxA 的调用确实发生的事实之外),所以我一直在摆弄东西并重新运行,但无济于事。为了将问题从我的语言细节中分离出来,我尝试通过自己填充所有参数来手动调用MessageBoxA,导致下面的代码仍然崩溃。
所以我的问题提炼为:我怎么能得到下面的代码片段运行下QT Creator/MinGW和实际显示一个消息框?
#include "libffi/include/ffi.h"
#include <QLibrary>
void testMessageBox()
{
int n = 4;
ffi_cif cif;
ffi_type **ffi_argTypes = new ffi_type*[n];
void **values = new void*[n];
values[0] = new ulong(0);
values[1] = (void *) "hello";
values[2] = (void *) "mommy";
values[3] = new int32_t(0);
ffi_argTypes[0] = &ffi_type_ulong;
ffi_argTypes[1] = &ffi_type_pointer;
ffi_argTypes[2] = &ffi_type_pointer;
ffi_argTypes[3] = &ffi_type_uint32;
ffi_type *c_retType = &ffi_type_sint32;
int32_t rc; // return value
if (ffi_prep_cif(&cif, FFI_STDCALL, n, c_retType, ffi_argTypes) == FFI_OK)
{
QLibrary lib("user32.dll");
lib.load();
void *msgbox = lib.resolve("MessageBoxA");
ffi_call(&cif, (void (*)()) msgbox, &rc, values);
}
}
您应该将地址传递给values数组而不是value。mingw64下的工作代码为
#include <stdio.h>
#include <ffi.h>
#include <Windows.h>
int main()
{
ffi_cif cif;
HINSTANCE dllHandle = LoadLibrary("user32.dll");
int n = 4;
ffi_type *ffi_argTypes[4];
void *values[4];
UINT64 a=0;
UINT32 b=0;
TCHAR* s1= "hello";
TCHAR* s2= "hello2";
values[0] = &a;
values[1] = &s1;
values[2] = &s2;
values[3] = &b;
ffi_argTypes[0] = &ffi_type_uint64;
ffi_argTypes[1] = &ffi_type_pointer;
ffi_argTypes[2] = &ffi_type_pointer;
ffi_argTypes[3] = &ffi_type_uint;
ffi_type *c_retType = &ffi_type_sint;
ffi_type rc; // return value
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 4, &ffi_type_sint, ffi_argTypes) == FFI_OK) {
ffi_call(&cif, FFI_FN(GetProcAddress(dllHandle,"MessageBoxA")), &rc, values);
}
return 0;
}
相关文章:
- Active Directory:从网络服务帐户下运行的Windows服务调用ADsOpenObject时失败
- 如何从Windows控制台调用.exe(C++)以在不同的目录(或任何目录)中创建文件夹?
- 意外的 IConnectionPointImpl::不建议调用 Windows Embedded Compact 7
- 如何链接 DLL 以供 LoadLibrary() 使用(在 Windows 上的 C++ 中)并从调用 exe 导入变
- 程序在对mouse_event的 Windows API 调用中冻结
- Windows 是否可以调用静态库中的 WinMain 函数C++
- 从 dll 调用 opencv 垫到 Windows 表单,图像出现故障
- 从 Python 调用 Windows DLL 函数时出错
- 从 C# Windows 应用程序调用 C dll 会导致 svchost.exe 崩溃
- 何时调用 Windows 控制台应用程序需要 CoInitialize
- C 控制台程序中的内存泄漏调用Windows API
- Win32应用程序,在调用Windows内容之前调用自定义类方法
- 哪个线程调用windows proc回调函数
- 最好声明什么来调用Windows程序的约定
- 在资源管理器左窗格上两次调用Windows 7外壳扩展dll Initialize方法
- 从Windows窗体外部(从int WINAPI WinMain)调用Windows窗体方法
- 如何以编程方式调用Windows 7中的Ctrl+Alt+Del窗口
- 调用windows API内联程序集时出现问题
- 在MinGW上使用libffi调用Windows API
- 在ImpersonateLoggedOnUser()之后,为什么无法调用Windows API SetDisplayCo