Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Странный Access violation в winapi приложении в Release (http://forum.oszone.net/showthread.php?t=234247)

crashtuak 08-05-2012 13:05 1912442

Странный Access violation в winapi приложении в Release
 
Вот в Release конфигурации получаю странный Access violation (0xC0000005: Access violation reading location 0x5e33e279). В Debug конфигурации все отлично. Валится после нажатия кнопки "хрестик". И самое главное, валится только из Студии, если просто запустить, выходит нормально, возвращает 0. Валится в __tmainCRTStartup на строчке "while (*lpszCommandLine > SPACECHAR || *lpszCommandLine&&inDoubleQuote)) {" (512 линия crtexe.c). lpszCommandLine на момент Access violation пустая, это может быть причиной? И еще странно, почему __tmainCRTStartup вызывается при закрытии приложения? :) (логика подсказывает, что должно вызываться в начале выполнения)
Если надо, код программы:
код, большой и непонятный

Код:

// cairo_test.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "cairo_test.h"

#include <cairo.h>
#include <cairo-win32.h>
#include <cairo-ft.h>


#include <ft2build.h>
#include FT_FREETYPE_H
#include <freetype/ftadvanc.h>
#include <freetype/ftsnames.h>
#include <freetype/tttables.h>

#include <hb.h>
#include <hb-ft.h>
#include <hb-buffer.h>
#include <harfbuzz_unicode_funcs.h>

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;                                                                // current instance
TCHAR szTitle[MAX_LOADSTRING];                                        // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];                        // the main window class name

// Forward declarations of functions included in this code module:
ATOM                                MyRegisterClass(HINSTANCE hInstance);
BOOL                                InitInstance(HINSTANCE, int);
LRESULT CALLBACK        WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK        About(HWND, UINT, WPARAM, LPARAM);
void init();
int APIENTRY _tWinMain(HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPTSTR    lpCmdLine,
                    int      nCmdShow)
{
        //UNREFERENCED_PARAMETER(hPrevInstance);
        //UNREFERENCED_PARAMETER(lpCmdLine);
        init();
        // TODO: Place code here.
        MSG msg;
        HACCEL hAccelTable;

        // Initialize global strings
        LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
        LoadString(hInstance, IDC_CAIRO_TEST, szWindowClass, MAX_LOADSTRING);
        MyRegisterClass(hInstance);

        // Perform application initialization:
        if (!InitInstance (hInstance, nCmdShow))
        {
                return FALSE;
        }

        hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_CAIRO_TEST));

        // Main message loop:
        while (GetMessage(&msg, NULL, 0, 0))
        {
                if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
                {
                        TranslateMessage(&msg);
                        DispatchMessage(&msg);
                }
        }

        //return (int) msg.wParam;
        return (int) msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage are only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
        WNDCLASSEX wcex;

        wcex.cbSize = sizeof(WNDCLASSEX);

        wcex.style                        = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc        = WndProc;
        wcex.cbClsExtra                = 0;
        wcex.cbWndExtra                = 0;
        wcex.hInstance                = hInstance;
        wcex.hIcon                        = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_CAIRO_TEST));
        wcex.hCursor                = LoadCursor(NULL, IDC_ARROW);
        wcex.hbrBackground        = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName        = MAKEINTRESOURCE(IDC_CAIRO_TEST);
        wcex.lpszClassName        = szWindowClass;
        wcex.hIconSm                = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

        return RegisterClassEx(&wcex);
}

//
//  FUNCTION: InitInstance(HINSTANCE, int)
//
//  PURPOSE: Saves instance handle and creates main window
//
//  COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
  HWND hWnd;

  hInst = hInstance; // Store instance handle in our global variable

  hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

  if (!hWnd)
  {
      return FALSE;
  }

  ShowWindow(hWnd, nCmdShow);
  UpdateWindow(hWnd);

  return TRUE;
}

//
//  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  PURPOSE:  Processes messages for the main window.
//
//  WM_COMMAND        - process the application menu
//  WM_PAINT        - Paint the main window
//  WM_DESTROY        - post a quit message and return
//
//
wchar_t *texts[5] = {
    L"This is some english text",
        L"??? ?? ??? ?????? ??????",
    L"??????",
        L"Это пример русского текста, с различными символами !%?(*%№ ёЁъЪ",
        L"Це приклад українського тексту, з різнимим символами !%?(*%№ ї"
};

const hb_direction_t text_directions[5] = {
    HB_DIRECTION_LTR,
    HB_DIRECTION_RTL,
    HB_DIRECTION_LTR,
        HB_DIRECTION_LTR,
        HB_DIRECTION_LTR
};

/* XXX: I don't know if these are correct or not, it doesn't seem to break anything
 *      regardless of their value. */
const char *languages[5] = {
    "en",
    "ar",
    "ch",
        "ru",
        "ua"
};

const hb_script_t scripts[5] = {
    HB_SCRIPT_LATIN,
    HB_SCRIPT_ARABIC,
        HB_SCRIPT_HAN,
        HB_SCRIPT_CYRILLIC,
        HB_SCRIPT_CYRILLIC
};

enum {
    ENGLISH=0, ARABIC, CHINESE, RUSSIAN, UKRAINE
};
double ptSize      = 50.0;
int    device_hdpi = 100;
int    device_vdpi = 100;


FT_Face ft_face[5];
cairo_font_face_t *cairo_ft_face[5];
hb_font_t *hb_ft_font[5];
hb_face_t *hb_ft_face[5];

void init()
{
            /* Init freetype */
    int error = 0;
        FT_Library ft_library;
    error = FT_Init_FreeType(&ft_library);
       
    /* Load our fonts */
   
    error = FT_New_Face(ft_library, "C:\\Work\\ex-sdl-cairo-freetype-harfbuzz\\fonts\\DejaVuSerif.ttf", 0, &ft_face[ENGLISH]);
    error = FT_Set_Char_Size(ft_face[ENGLISH], 0, ptSize, device_hdpi, device_vdpi );
    error = FT_New_Face(ft_library, "C:\\Work\\ex-sdl-cairo-freetype-harfbuzz\\fonts\\lateef.ttf", 0, &ft_face[ARABIC]);
    error = FT_Set_Char_Size(ft_face[ARABIC], 0, ptSize, device_hdpi, device_vdpi );
    error = FT_New_Face(ft_library, "C:\\Work\\ex-sdl-cairo-freetype-harfbuzz\\fonts\\fireflysung-1.3.0\\fireflysung.ttf", 0, &ft_face[CHINESE]);
    error = FT_Set_Char_Size(ft_face[CHINESE], 0, ptSize, device_hdpi, device_vdpi );
        error = FT_New_Face(ft_library, "C:\\Work\\ex-sdl-cairo-freetype-harfbuzz\\fonts\\DejaVuSerif.ttf", 0, &ft_face[RUSSIAN]);
    error = FT_Set_Char_Size(ft_face[RUSSIAN], 0, ptSize, device_hdpi, device_vdpi );
        error = FT_New_Face(ft_library, "C:\\Work\\ex-sdl-cairo-freetype-harfbuzz\\fonts\\DejaVuSerif.ttf", 0, &ft_face[UKRAINE]);
    error = FT_Set_Char_Size(ft_face[UKRAINE], 0, ptSize, device_hdpi, device_vdpi );
        //assert(!FT_Select_Charmap(ft_face[CHINESE],FT_Encoding::FT_ENCODING_MS_SYMBOL));
    /* Get our cairo font structs */
   
    cairo_ft_face[ENGLISH] = cairo_ft_font_face_create_for_ft_face(ft_face[ENGLISH], 0);
    cairo_ft_face[ARABIC]  = cairo_ft_font_face_create_for_ft_face(ft_face[ARABIC], 0);
    cairo_ft_face[CHINESE] = cairo_ft_font_face_create_for_ft_face(ft_face[CHINESE], 0);
        cairo_ft_face[RUSSIAN] = cairo_ft_font_face_create_for_ft_face(ft_face[RUSSIAN], 0);
        cairo_ft_face[UKRAINE] = cairo_ft_font_face_create_for_ft_face(ft_face[UKRAINE], 0);
    /* Get our harfbuzz font/face structs */
    hb_ft_font[ENGLISH] = hb_ft_font_create(ft_face[ENGLISH], NULL);
    hb_ft_face[ENGLISH] = hb_ft_face_create(ft_face[ENGLISH], NULL);
    hb_ft_font[ARABIC]  = hb_ft_font_create(ft_face[ARABIC] , NULL);
    hb_ft_face[ARABIC]  = hb_ft_face_create(ft_face[ARABIC] , NULL);
    hb_ft_font[CHINESE] = hb_ft_font_create(ft_face[CHINESE], NULL);
    hb_ft_face[CHINESE] = hb_ft_face_create(ft_face[CHINESE], NULL);
        hb_ft_font[RUSSIAN] = hb_ft_font_create(ft_face[RUSSIAN], NULL);
    hb_ft_face[RUSSIAN] = hb_ft_face_create(ft_face[RUSSIAN], NULL);
        hb_ft_font[UKRAINE] = hb_ft_font_create(ft_face[UKRAINE], NULL);
    hb_ft_face[UKRAINE] = hb_ft_face_create(ft_face[UKRAINE], NULL);
}
void cr_draw(cairo_t *cr)
{
//        cairo_set_source_rgba (cr, 0.3, 0.6, 1, 1);
//        cairo_paint (cr);
//        cairo_set_source_rgba (cr, 0, 0, 0, 1);
        int x = 0;
    int y = 100;
    for (int i=0; i < 5; ++i) {
                x = 0;
        /* Create a buffer for harfbuzz to use */
        hb_buffer_t *buf = hb_buffer_create();
                //alternatively you can use hb_buffer_set_unicode_funcs(buf, hb_glib_get_unicode_funcs());
        hb_buffer_set_unicode_funcs(buf, hb_moz_get_unicode_funcs());
        hb_buffer_set_direction(buf, text_directions[i]); /* or LTR */
        hb_buffer_set_script(buf, scripts[i]); /* see hb-unicode.h */
        hb_buffer_set_language(buf, hb_language_from_string(languages[i],2));
                /* Layout the text */
                for(int k = 0; k < wcslen(texts[i]);k++)
                {
                        hb_buffer_add(buf,texts[i][k],0,0);
                }
        hb_shape(hb_ft_font[i], buf, NULL, 0);
                /* Hand the layout to cairo to render */
        int                  glyph_count  = hb_buffer_get_length(buf);
                unsigned int size = (unsigned int) glyph_count;
        hb_glyph_info_t    *glyph_info  = hb_buffer_get_glyph_infos(buf,&size);
        hb_glyph_position_t *glyph_pos    = hb_buffer_get_glyph_positions(buf,&size);
        cairo_glyph_t      *cairo_glyphs = (cairo_glyph_t *)malloc(sizeof(cairo_glyph_t) * glyph_count);
        for (int i=0; i < glyph_count; ++i) {
                        cairo_glyphs[i].index = glyph_info[i].codepoint;
                        //cairo_glyphs[i].index = FT_Get_Char_Index(ft_face[CHINESE],L'Ы');
            cairo_glyphs[i].x = x;
            cairo_glyphs[i].y = y;
            x += glyph_pos[i].x_advance/64;
            y += glyph_pos[i].y_advance/64;
                }
                cairo_set_source_rgba (cr, 0.5, 0.5, 0.5, 1.0);
                cairo_set_font_face(cr, cairo_ft_face[i]);
                cairo_set_font_size(cr, ptSize);
                cairo_show_glyphs(cr, cairo_glyphs, glyph_count);

                free(cairo_glyphs);
        hb_buffer_destroy(buf);
        y += 100;
        }
}
int nWidth;
int nHeight;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
        int wmId, wmEvent;
        PAINTSTRUCT ps;
        HDC hdc;

        switch (message)
        {
        case WM_COMMAND:
                wmId    = LOWORD(wParam);
                wmEvent = HIWORD(wParam);
                // Parse the menu selections:
                switch (wmId)
                {
                case IDM_about:
                        DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                        break;
                case IDM_EXIT:
                        DestroyWindow(hWnd);
                        break;
                default:
                        return DefWindowProc(hWnd, message, wParam, lParam);
                }
                break;
        case WM_PAINT:
                {
                        hdc = BeginPaint(hWnd, &ps);
                        cairo_surface_t *surface;
                        cairo_t *cr;
                        //surface = cairo_win32_surface_create(hdc);
                        surface = cairo_win32_surface_create_with_dib(CAIRO_FORMAT_ARGB32, nWidth, nHeight);
                        cr = cairo_create (surface);
                        cr_draw(cr);
                        HDC src = cairo_win32_surface_get_dc(surface); // <--------
                        BitBlt(hdc, 0, 0, nWidth, nHeight, src, 0,0, SRCCOPY); // <--------
                        cairo_destroy(cr);
                        cairo_surface_destroy(surface);
                        //cairo_surface_t *surface;
                                //cairo_t *cr;
                        //surface = cairo_win32_surface_create(hdc);
                    //cr = cairo_create(surface);
                        //cr_draw(cr);  //  <<<<<<Cairo draw here
                        //cairo_destroy(cr);
                        EndPaint(hWnd, &ps);
                        break;
                }
                case WM_SIZE:
        {
                        nWidth = LOWORD(lParam);
            nHeight = HIWORD(lParam);
            break;
        }
        case WM_DESTROY:
                PostQuitMessage(0);
                break;
        default:
                return DefWindowProc(hWnd, message, wParam, lParam);
        }
        return 0;
}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
        UNREFERENCED_PARAMETER(lParam);
        switch (message)
        {
        case WM_INITDIALOG:
                return (INT_PTR)TRUE;

        case WM_COMMAND:
                if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
                {
                        EndDialog(hDlg, LOWORD(wParam));
                        return (INT_PTR)TRUE;
                }
                break;
        }
        return (INT_PTR)FALSE;
}


с программированием на с++ я потихоньку забываю про логику, тут почему то мне все кажется совсем не логичным:)


Время: 18:49.

Время: 18:49.
© OSzone.net 2001-