Hi Martin,
It's very likely that it's a problem with ABI. Wine had a problem with
this function due to incompatibility of stdcall already:
https://www.winehq.org/pipermail/wine-patches/2014-September/134351.html
Unless stdcall is handled differently for mingw target, we need to fix
it in mingw as well. Kai may know more about this.
Jacek
On 12/23/14 11:55, Martin Mitáš wrote:
> "Fixed" the DemoApp.cpp by rewriting the line 216 as follows:
>
> // D2D1_SIZE_F rtSize = m_pRenderTarget->GetSize();
> D2D1_SIZE_F rtSize = { 640, 480 };
>
> Seems that calling ID2D1RenderTarget::GetSize() is broken when
> called from gcc-compiled object.
>
> This particular method is a bit uncommon in that it returns
> a structure (with two float members) instead of a scalar type
> such as HRESULT or void.
>
> Perhaps there is some bug/incompatibility between MS ABI and gcc
> in such case?
>
> Martin
>
>
>
> Dne 23. 12. 2014 v 7:28 Jack Andrews napsal(a):
>> Hi,
>>
>> The sample on msdn (and the SDK) "Draw Rectangle Example"
>>
>>
>> http://msdn.microsoft.com/en-us/library/windows/desktop/dd371016(v=vs.85).aspx
>>
>> ...runs when built in Visual Studio Express 2010 (32 bit compiled) but fails
>> when built on mingw-64 (also 32bit).
>>
>> I've appended the source for convenience. Many thanks in advance.
>>
>> Jack.
>>
>> $ g++ -m32 -mwindows -g DemoApp.cpp -o d -L/mingw/lib -lole32 -loleaut32
>> -ld2d1
>>
>> jack@tp ~/g
>> $ gdb ./d
>> GNU gdb (GDB) 7.6.1
>> Copyright (C) 2013 Free Software Foundation, Inc.
>> License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
>> This is free software: you are free to change and redistribute it.
>> There is NO WARRANTY, to the extent permitted by law. Type "show copying"
>> and "show warranty" for details.
>> This GDB was configured as "i686-w64-mingw32".
>> For bug reporting instructions, please see:
>> <http://www.gnu.org/software/gdb/bugs/>...
>> Reading symbols from c:\Users\jack\g\d.exe...done.
>> (gdb) r
>> Starting program: c:\Users\jack\g/./d.exe
>> [New Thread 73872.0x3294]
>> [New Thread 73872.0x12bd0]
>>
>> Program received signal SIGSEGV, Segmentation fault.
>> 0x77226c41 in d2d1!D2D1InvertMatrix () from C:\Windows\SysWOW64\d2d1.dll
>> (gdb) where
>> #0 0x77226c41 in d2d1!D2D1InvertMatrix () from C:\Windows\SysWOW64\d2d1.dll
>> #1 0x7721ef62 in d2d1!D2D1InvertMatrix () from C:\Windows\SysWOW64\d2d1.dll
>> #2 0x0040220b in DemoApp::OnRender (this=0x28fe6c) at DemoApp.cpp:222
>> #3 0x0040292a in DemoApp::WndProc (hwnd=0x6e129c, message=15, wParam=0,
>> lParam=0) at DemoApp.cpp:348
>> #4 0x748d62fa in gapfnScSendMessage () from C:\Windows\syswow64\user32.dll
>> #5 0x006e129c in ?? ()
>> #6 0x748d6d3a in USER32!GetThreadDesktop ()
>> from C:\Windows\syswow64\user32.dll
>> #7 0x00402818 in DemoApp::OnResize(unsigned int, unsigned int) ()
>> at DemoApp.cpp:294
>> #8 0x748d6de8 in USER32!GetThreadDesktop ()
>> from C:\Windows\syswow64\user32.dll
>> #9 0x00000000 in ?? ()
>> (gdb)
>>
>> jack@tp ~/g
>> $ g++ -v
>> Reading specs from c:/mingw/bin/../lib/gcc/i686-w64-mingw32/4.8.2/specs
>> COLLECT_GCC=c:\mingw\bin\g++.exe
>> COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/i686-w64-mingw32/4.8.2/lto-wrapper.exe
>> Target: i686-w64-mingw32
>> Configured with: ../gcc-4.8.2/configure --prefix=/opt/windows_32
>> --with-sysroot=/opt/windows_32 --libdir=/opt/windows_32/lib
>> --mandir=/opt/windows_32/man --infodir=/opt/windows_32/info --enable-shared
>> --disable-bootstrap --disable-multilib --with-arch=pentium3
>> --enable-threads=posix --enable-languages=c,c++ --enable-checking=release
>> --with-system-zlib --with-python-dir=/lib/python2.7/site-packages
>> --disable-libunwind-exceptions --enable-__cxa_atexit --enable-libssp
>> --with-gnu-ld --verbose --enable-java-home
>> --with-java-home=/opt/windows_32/lib/jvm/jre
>> --with-jvm-root-dir=/opt/windows_32/lib/jvm
>> --with-jvm-jar-dir=/opt/windows_32/lib/jvm/jvm-exports
>> --with-arch-directory=amd64
>> --with-antlr-jar='/home/adrien/projects/win-builds-1.4/slackware64-current/d/gcc/antlr-*.jar'
>> --disable-java-awt --disable-gtktest --build=x86_64-slackware-linux
>> --host=i686-w64-mingw32 --target=i686-w64-mingw32
>> Thread model: posix
>> gcc version 4.8.2 (GCC)
>>
>>
>> $ cat DemoApp.cpp
>> // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
>> // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
>> // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
>> // PARTICULAR PURPOSE.
>> //
>> // Copyright (c) Microsoft Corporation. All rights reserved
>>
>> #include "DemoApp.h"
>>
>> // Provides the application entry point.
>> int WINAPI WinMain(
>> HINSTANCE /* hInstance */,
>> HINSTANCE /* hPrevInstance */,
>> LPSTR /* lpCmdLine */,
>> int /* nCmdShow */
>> )
>> {
>> // Use HeapSetInformation to specify that the process should
>> // terminate if the heap manager detects an error in any heap used
>> // by the process.
>> // The return value is ignored, because we want to continue running in
>> the
>> // unlikely event that HeapSetInformation fails.
>> HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0);
>>
>> if (SUCCEEDED(CoInitialize(NULL)))
>> {
>> {
>> DemoApp app;
>>
>> if (SUCCEEDED(app.Initialize()))
>> {
>> app.RunMessageLoop();
>> }
>> }
>> CoUninitialize();
>> }
>>
>> return 0;
>> }
>>
>> // DemoApp constructor
>> DemoApp::DemoApp() :
>> m_hwnd(NULL),
>> m_pDirect2dFactory(NULL),
>> m_pRenderTarget(NULL),
>> m_pLightSlateGrayBrush(NULL),
>> m_pCornflowerBlueBrush(NULL)
>> {
>> }
>>
>> // DemoApp destructor
>> // Releases the application's resources.
>> DemoApp::~DemoApp()
>> {
>> SafeRelease(&m_pDirect2dFactory);
>> SafeRelease(&m_pRenderTarget);
>> SafeRelease(&m_pLightSlateGrayBrush);
>> SafeRelease(&m_pCornflowerBlueBrush);
>>
>> }
>>
>> // Creates the application window and device-independent
>> // resources.
>> HRESULT DemoApp::Initialize()
>> {
>> HRESULT hr;
>>
>> // Initialize device-indpendent resources, such
>> // as the Direct2D factory.
>> hr = CreateDeviceIndependentResources();
>>
>> if (SUCCEEDED(hr))
>> {
>> // Register the window class.
>> WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
>> wcex.style = CS_HREDRAW | CS_VREDRAW;
>> wcex.lpfnWndProc = DemoApp::WndProc;
>> wcex.cbClsExtra = 0;
>> wcex.cbWndExtra = sizeof(LONG_PTR);
>> wcex.hInstance = HINST_THISCOMPONENT;
>> wcex.hbrBackground = NULL;
>> wcex.lpszMenuName = NULL;
>> wcex.hCursor = LoadCursor(NULL, IDI_APPLICATION);
>> wcex.lpszClassName = L"D2DDemoApp";
>>
>> RegisterClassEx(&wcex);
>>
>>
>> // Because the CreateWindow function takes its size in pixels,
>> // obtain the system DPI and use it to scale the window size.
>> FLOAT dpiX, dpiY;
>>
>> // The factory returns the current system DPI. This is also the
>> value it will use
>> // to create its own windows.
>> m_pDirect2dFactory->GetDesktopDpi(&dpiX, &dpiY);
>>
>>
>> // Create the window.
>> m_hwnd = CreateWindow(
>> L"D2DDemoApp",
>> L"Direct2D Demo App",
>> WS_OVERLAPPEDWINDOW|WS_VISIBLE,
>> CW_USEDEFAULT,
>> CW_USEDEFAULT,
>> static_cast<UINT>(ceil(640.f * dpiX / 96.f)),
>> static_cast<UINT>(ceil(480.f * dpiY / 96.f)),
>> NULL,
>> NULL,
>> HINST_THISCOMPONENT,
>> this
>> );
>> hr = m_hwnd ? S_OK : E_FAIL;
>> if (SUCCEEDED(hr))
>> {
>> ShowWindow(m_hwnd, SW_SHOWNORMAL);
>> UpdateWindow(m_hwnd);
>> }
>> }
>>
>> return hr;
>> }
>>
>> // Creates resources that are not bound to a particular device.
>> // Their lifetime effectively extends for the duration of the
>> // application.
>> HRESULT DemoApp::CreateDeviceIndependentResources()
>> {
>> HRESULT hr = S_OK;
>>
>> // Create a Direct2D factory.
>> hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED,
>> &m_pDirect2dFactory);
>>
>> return hr;
>> }
>>
>>
>> // Creates resources that are bound to a particular
>> // Direct3D device. These resources need to be recreated
>> // if the Direct3D device dissapears, such as when the display
>> // changes, the window is remoted, etc.
>> HRESULT DemoApp::CreateDeviceResources()
>> {
>> HRESULT hr = S_OK;
>>
>> if (!m_pRenderTarget)
>> {
>> RECT rc;
>> GetClientRect(m_hwnd, &rc);
>>
>> D2D1_SIZE_U size = D2D1::SizeU(
>> rc.right - rc.left,
>> rc.bottom - rc.top
>> );
>>
>> // Create a Direct2D render target.
>> hr = m_pDirect2dFactory->CreateHwndRenderTarget(
>> D2D1::RenderTargetProperties(),
>> D2D1::HwndRenderTargetProperties(m_hwnd, size),
>> &m_pRenderTarget
>> );
>>
>>
>> if (SUCCEEDED(hr))
>> {
>> // Create a gray brush.
>> hr = m_pRenderTarget->CreateSolidColorBrush(
>> D2D1::ColorF(D2D1::ColorF::LightSlateGray),
>> &m_pLightSlateGrayBrush
>> );
>> }
>> if (SUCCEEDED(hr))
>> {
>> // Create a blue brush.
>> hr = m_pRenderTarget->CreateSolidColorBrush(
>> D2D1::ColorF(D2D1::ColorF::CornflowerBlue),
>> &m_pCornflowerBlueBrush
>> );
>> }
>> }
>>
>> return hr;
>> }
>>
>> // Discards device-dependent resources. These resources must be
>> // recreated when the Direct3D device is lost.
>> void DemoApp::DiscardDeviceResources()
>> {
>> SafeRelease(&m_pRenderTarget);
>> SafeRelease(&m_pLightSlateGrayBrush);
>> SafeRelease(&m_pCornflowerBlueBrush);
>> }
>>
>> // Runs the main window message loop.
>> void DemoApp::RunMessageLoop()
>> {
>> MSG msg;
>>
>> while (GetMessage(&msg, NULL, 0, 0))
>> {
>> TranslateMessage(&msg);
>> DispatchMessage(&msg);
>> }
>> }
>>
>> // This method discards device-specific
>> // resources if the Direct3D device dissapears during execution and
>> // recreates the resources the next time it's invoked.
>> HRESULT DemoApp::OnRender()
>> {
>> HRESULT hr = S_OK;
>>
>> hr = CreateDeviceResources();
>>
>> if (SUCCEEDED(hr))
>> {
>> m_pRenderTarget->BeginDraw();
>>
>> m_pRenderTarget->SetTransform(D2D1::Matrix3x2F::Identity());
>>
>> m_pRenderTarget->Clear(D2D1::ColorF(D2D1::ColorF::White));
>>
>> D2D1_SIZE_F rtSize = m_pRenderTarget->GetSize();
>>
>> // Draw a grid background.
>> int width = static_cast<int>(rtSize.width);
>> int height = static_cast<int>(rtSize.height);
>>
>> for (int x = 0; x < width; x += 10)
>> {
>> m_pRenderTarget->DrawLine(
>> D2D1::Point2F(static_cast<FLOAT>(x), 0.0f),
>> D2D1::Point2F(static_cast<FLOAT>(x), rtSize.height),
>> m_pLightSlateGrayBrush,
>> 0.5f
>> );
>> }
>>
>> for (int y = 0; y < height; y += 10)
>> {
>> m_pRenderTarget->DrawLine(
>> D2D1::Point2F(0.0f, static_cast<FLOAT>(y)),
>> D2D1::Point2F(rtSize.width, static_cast<FLOAT>(y)),
>> m_pLightSlateGrayBrush,
>> 0.5f
>> );
>> }
>>
>> // Draw two rectangles.
>> D2D1_RECT_F rectangle1 = D2D1::RectF(
>> rtSize.width/2 - 50.0f,
>> rtSize.height/2 - 50.0f,
>> rtSize.width/2 + 50.0f,
>> rtSize.height/2 + 50.0f
>> );
>>
>> D2D1_RECT_F rectangle2 = D2D1::RectF(
>> rtSize.width/2 - 100.0f,
>> rtSize.height/2 - 100.0f,
>> rtSize.width/2 + 100.0f,
>> rtSize.height/2 + 100.0f
>> );
>>
>>
>> // Draw a filled rectangle.
>> m_pRenderTarget->FillRectangle(&rectangle1, m_pLightSlateGrayBrush);
>>
>> // Draw the outline of a rectangle.
>> m_pRenderTarget->DrawRectangle(&rectangle2, m_pCornflowerBlueBrush);
>>
>> hr = m_pRenderTarget->EndDraw();
>> }
>>
>> if (hr == D2DERR_RECREATE_TARGET)
>> {
>> hr = S_OK;
>> DiscardDeviceResources();
>> }
>>
>> return hr;
>> }
>>
>>
>> // If the application receives a WM_SIZE message, this method
>> // resizes the render target appropriately.
>> void DemoApp::OnResize(UINT width, UINT height)
>> {
>> if (m_pRenderTarget)
>> {
>> // Note: This method can fail, but it's okay to ignore the
>> // error here, because the error will be returned again
>> // the next time EndDraw is called.
>> m_pRenderTarget->Resize(D2D1::SizeU(width, height));
>> }
>> }
>>
>> // Handles window messages.
>> LRESULT CALLBACK DemoApp::WndProc(HWND hwnd, UINT message, WPARAM wParam,
>> LPARAM lParam)
>> {
>> LRESULT result = 0;
>>
>> if (message == WM_CREATE)
>> {
>> LPCREATESTRUCT pcs = (LPCREATESTRUCT)lParam;
>> DemoApp *pDemoApp = (DemoApp *)pcs->lpCreateParams;
>>
>> ::SetWindowLongPtrW(
>> hwnd,
>> GWLP_USERDATA,
>> PtrToUlong(pDemoApp)
>> );
>>
>> result = 1;
>> }
>> else
>> {
>> DemoApp *pDemoApp = reinterpret_cast<DemoApp
>> *>(static_cast<LONG_PTR>(
>> ::GetWindowLongPtrW(
>> hwnd,
>> GWLP_USERDATA
>> )));
>>
>> bool wasHandled = false;
>>
>> if (pDemoApp)
>> {
>> switch (message)
>> {
>> case WM_SIZE:
>> {
>> UINT width = LOWORD(lParam);
>> UINT height = HIWORD(lParam);
>> pDemoApp->OnResize(width, height);
>> }
>> result = 0;
>> wasHandled = true;
>> break;
>>
>> case WM_DISPLAYCHANGE:
>> {
>> InvalidateRect(hwnd, NULL, FALSE);
>> }
>> result = 0;
>> wasHandled = true;
>> break;
>>
>> case WM_PAINT:
>> {
>> pDemoApp->OnRender();
>> ValidateRect(hwnd, NULL);
>> }
>> result = 0;
>> wasHandled = true;
>> break;
>>
>> case WM_DESTROY:
>> {
>> PostQuitMessage(0);
>> }
>> result = 1;
>> wasHandled = true;
>> break;
>> }
>> }
>>
>> if (!wasHandled)
>> {
>> result = DefWindowProc(hwnd, message, wParam, lParam);
>> }
>> }
>>
>> return result;
>> }
>>
>> jack@tp ~/g
>> $ cat DemoApp.h
>> // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
>> // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
>> // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
>> // PARTICULAR PURPOSE.
>> //
>> // Copyright (c) Microsoft Corporation. All rights reserved
>> //
>> #pragma once
>>
>> // Modify the following defines if you have to target a platform prior to
>> the ones specified below.
>> // Refer to MSDN for the latest info on corresponding values for different
>> platforms.
>> #ifndef WINVER // Allow use of features specific to Windows 7
>> or later.
>> #define WINVER 0x0700 // Change this to the appropriate value to
>> target other versions of Windows.
>> #endif
>>
>> #ifndef _WIN32_WINNT // Allow use of features specific to Windows 7
>> or later.
>> #define _WIN32_WINNT 0x0700 // Change this to the appropriate value to
>> target other versions of Windows.
>> #endif
>>
>> #ifndef UNICODE
>> #define UNICODE
>> #endif
>>
>> // Exclude rarely-used items from Windows headers.
>> #define WIN32_LEAN_AND_MEAN
>>
>> // Windows Header Files:
>> #include <windows.h>
>>
>> // C RunTime Header Files:
>> #include <stdlib.h>
>> #include <malloc.h>
>> #include <memory.h>
>> #include <wchar.h>
>> #include <math.h>
>>
>> #include <d2d1.h>
>> #include <d2d1helper.h>
>> #include <dwrite.h>
>> #include <wincodec.h>
>>
>> /******************************************************************
>> * *
>> * Macros *
>> * *
>> ******************************************************************/
>> template<class Interface>
>> inline void SafeRelease(
>> Interface **ppInterfaceToRelease
>> )
>> {
>> if (*ppInterfaceToRelease != NULL)
>> {
>> (*ppInterfaceToRelease)->Release();
>>
>> (*ppInterfaceToRelease) = NULL;
>> }
>> }
>>
>>
>> #ifndef Assert
>> #if defined( DEBUG ) || defined( _DEBUG )
>> #define Assert(b) do {if (!(b)) {OutputDebugStringA("Assert: " #b "\n");}}
>> while(0)
>>
>> else
>> #define Assert(b)
>> #endif //DEBUG || _DEBUG
>> #endif
>>
>>
>>
>> #ifndef HINST_THISCOMPONENT
>> EXTERN_C IMAGE_DOS_HEADER __ImageBase;
>> #define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
>> #endif
>>
>>
>> //
>> // DemoApp class declaration
>> //
>> class DemoApp
>> {
>> public:
>> DemoApp();
>> ~DemoApp();
>>
>> // Register the window class and call methods for instantiating drawing
>> resources
>> HRESULT Initialize();
>>
>> // Process and dispatch messages
>> void RunMessageLoop();
>>
>> private:
>> // Initialize device-independent resources.
>> HRESULT CreateDeviceIndependentResources();
>>
>> // Initialize device-dependent resources.
>> HRESULT CreateDeviceResources();
>>
>> // Release device-dependent resource.
>> void DiscardDeviceResources();
>>
>> // Draw content.
>> HRESULT OnRender();
>>
>> // Resize the render target.
>> void OnResize(
>> UINT width,
>> UINT height
>> );
>>
>> // The windows procedure.
>> static LRESULT CALLBACK WndProc(
>> HWND hWnd,
>> UINT message,
>> WPARAM wParam,
>> LPARAM lParam
>> );
>> private:
>> HWND m_hwnd;
>> ID2D1Factory* m_pDirect2dFactory;
>> ID2D1HwndRenderTarget* m_pRenderTarget;
>> ID2D1SolidColorBrush* m_pLightSlateGrayBrush;
>> ID2D1SolidColorBrush* m_pCornflowerBlueBrush;
>> };
>>
>>
>>
>>
>>
>>
>>
>> ------------------------------------------------------------------------------
>> Dive into the World of Parallel Programming! The Go Parallel Website,
>> sponsored by Intel and developed in partnership with Slashdot Media, is your
>> hub for all things parallel software development, from weekly thought
>> leadership blogs to news, videos, case studies, tutorials and more. Take a
>> look and join the conversation now. http://goparallel.sourceforge.net
>>
>>
>>
>> _______________________________________________
>> Mingw-w64-public mailing list
>> [email protected]
>> https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
>>
> ------------------------------------------------------------------------------
> Dive into the World of Parallel Programming! The Go Parallel Website,
> sponsored by Intel and developed in partnership with Slashdot Media, is your
> hub for all things parallel software development, from weekly thought
> leadership blogs to news, videos, case studies, tutorials and more. Take a
> look and join the conversation now. http://goparallel.sourceforge.net
> _______________________________________________
> Mingw-w64-public mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
------------------------------------------------------------------------------
Dive into the World of Parallel Programming! The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public