How to Use the Windows API in Mingw

mingw std::thread with Windows API

Is there any way to use windows API calls which expect a thread handle with std::thread ?

No, because the std::thread in your MinGW build isn't implemented in terms of thread handles. Edit: it is, but indirectly, see rubenvb's answer for how to get the native thread handle from a pthread_t, and you should be able to use std::thread::native_handle() to get the pthread_t.

Noone has implemented the necessary support in GCC for the C++11 thread library to use native Windows threads directly.

I had some ideas for a new thead model that would be implemented in terms of native mutexes and condition variables. That would allow you to call std::thread::native_handle() to get the underlying thread handle to use with the Windows API.

I got as far as rebuilding GCC with my changes applied, but couldn't test them. There was almost no interest in my suggestions and no offers to help from any MinGW contributors, so as I'm not a Windows user, and working on Windows and building MinGW was so painful and frustrating, I gave up. I should put my changes online somewhere, so that someone with more patience than me can finish the work one day.

Native Windows API link problem on Qt + win32 + mingw

The functions CreateEnhMetaFileW() and CloseEnhMetaFile() are defined in the static library Gdi32.lib, so you have to make sure to link against that. Try adding -lgdi32 to the end of your command line you're using to compile. If that doesn't work, you might have to specify the full path to Gdi32.lib by adding -L/path/to/folder/containing/the/library -lgdi32 instead.

MinGW, g++, winapi, winsdk, lost in confusion

As I understand it, it is not practical to use the MS SDK with the mingw compiler. You have to use a mingw specific SDK. And even the most up-to-date mingw releases appear not to support GetPhysicalCursorPos.

Since you only need this one function, or perhaps this one and a handful of others, it is easy enough to supply the missing parts of the SDK yourself. For example:

#define WINVER 0x0600
#include <windows.h>
#include <iostream>

extern "C"
{
__declspec(dllimport) BOOL WINAPI GetPhysicalCursorPos(LPPOINT lpPoint);
}

int main()
{
POINT pt;
if (GetPhysicalCursorPos(&pt))
{
std::cout << pt.x << ", " << pt.y << std::endl;
}
}

Here we include a declaration of the API we wish to call. When you compile this you get the following error:


>g++ main.cpp -o main.exe
>C:\Users\xxx\AppData\Local\Temp\ccCCZZEk.o:main.cpp:(.text+0x1d): undefined
reference to `__imp_GetPhysicalCursorPos'
collect2.exe: error: ld returned 1 exit status

So we need to find a way for the linker to be able to resolve the symbol. In theory you can ask the linker, ld, to link to DLLs directly. But I have not been able to get that to work. Instead you can use a somewhat more laborious approach.

Make a .def file to define the exports of the user32 library where this function lives:


LIBRARY user32.dll
EXPORTS
GetPhysicalCursorPos = __imp_GetPhysicalCursorPos

Save that to a file named myuser32.def. Now, that's not all the functions that user32 exports, but we only want the ones that are missing from the import library that comes with mingw.

Now use dlltool to make an import library:


>dlltool -d myuser32.def -l myuser32.a

And then compile passing the import library:


>g++ main.cpp myuser32.a -o main.exe

Success this time. When we run the program:


>main
1302, 670

Calling Windows API with libffi on MinGW

you should pass the address to the values array instead of the values. the working code under mingw64 is

   #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;
}

Using the win32 API in vs code

The D2D1CreateFactory can't be found because you aren't linking D2d1.lib as specified in https://learn.microsoft.com/en-us/windows/win32/api/d2d1/nf-d2d1-d2d1createfactory.
Add -ld2d1 argument to command line. Maybe you need to use also -L directive to specify directory.

For MSVC compiler pragma directive can be used (which probably doesn't work for mingw).

#pragma comment(lib, "d2d1")

EDITED

Added "-ld2d1", just before "-o",.

        "args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-ld2d1",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],

Can g++ / minGW play nice with the Windows SDK? Is Visual Studio the only option?

I use MinGW to compile Windows programs every day, with zero problems. There must be something wrong with your installation - try the version at Twilight Dragon Media.

Edit: Just re-read your post - you do not need to specify the include directory as you are doing, and probably should not do so. Also, you may (or may not) need the slightly mysterious -mwindows flag. I just compiled your program using MinGW (TDM build) g++ 4.4.1, with the command line:

g++ main.cpp

with absolutely no problems.

More Info: Just so you know what the -mwindows flag does, the GCC docs say:

This option is available for Cygwin and
MinGW targets.It specifes that a GUI
application is to be generated by
instructing the linker to set the
PE header subsystem type appropriately.

Personally, I've never found it necessary, but then my Windows apps are all command line tools or servers.

Win32 API stack walk with MinGW/MSYS?

Check Mr. Edd's stack trace library at the following link. It will produce a nice stack frame listing and has specific code to support MinGW.

http://www.mr-edd.co.uk/code/stack_trace

His library uses dbghelp.dll, however, so you may get into some problems trying to compile it. As far as I know, MinGW doesn't include an import library for this DLL (see a old feature request here). I had success, however, creating one import library myself. You can do the same just using a .def file from the Wine project (check the previous link's attached files for one) and running the MingW utility dlltool:

dlltool -k -d dbghelp.def -l dbghelp.a

You can then include the resulting dbghelp.a file in your project. You won't probably like to have dependencies towards dbghelp.dll in your release builds, as the DLL itself is surely not redistributable.

Can not compile win32 C++ Using Mingw

You can work with two types of entry-point functions in WinAPI: WinMain and wWinMain.

The WinMain function is identical to wWinMain, except the command-line arguments are passed as an ANSI string. The Unicode version is preferred.

Source: Microsoft Docs

Both should work well with Microsoft Visual C++ compiler. However, there are some problems with MinGW and wWinMain function.

Solution 1: Use Microsoft Visual C++ compiler.

Solution 2: Use MinGW and change your entry-point function to WinMain because it works correctly on MinGW (also change PWSTR pCmdLine to PSTR pCmdLine):

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, PSTR pCmdLine, int nCmdShow)
^^^^^^^ ^^^^

Solution 3: It is discussed here but I didn't test it.
If you are using MinGW-w64, you can add

-municode as your command line option. Your original source code should be compiled correctly.



Related Topics



Leave a reply



Submit