Как использовать GDI + в C? - PullRequest
       57

Как использовать GDI + в C?

12 голосов
/ 25 февраля 2011

Отказ от ответственности: я только начинаю в C, так что, скорее всего, я упускаю что-то очевидное или не думаю, что правильно! :)

Как именно я бы использовал GDI + в чистом C? Насколько я понимаю, в GDI + есть обернутые объекты, созданные для C ++, но под ним лежит плоский API, доступный через gdiplusflat.h, дружественный для C заголовок.

Моя проблема в том, что когда я #include его, я получаю следующие ошибки:

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\gdiplusflat.h(30) : error C2143: syntax error : missing '{' before '__stdcall'
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\gdiplusflat.h(31) : error C2146: syntax error : missing ')' before identifier 'brushMode'
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\gdiplusflat.h(31) : error C2061: syntax error : identifier 'brushMode'
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\gdiplusflat.h(31) : error C2059: syntax error : ';'
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\gdiplusflat.h(31) : error C2059: syntax error : ','
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\include\gdiplusflat.h(31) : error C2059: syntax error : ')'
and 100 more...

Теперь я думаю, что эти ошибки вызваны тем, что GpStatus не определен, потому что просмотр GdiPlusFlat.h показывает, что все функции имеют стиль:

// WINGDIAPI is #defined as __stdcall
GpStatus WINGDIPAPI
GdipCreatePath(GpFillMode brushMode, GpPath **path);
GpStatus WINGDIPAPI
GdipCreatePath2(GDIPCONST GpPointF*, GDIPCONST BYTE*, INT, GpFillMode,
                                    GpPath **path);
GpStatus WINGDIPAPI
GdipCreatePath2I(GDIPCONST GpPoint*, GDIPCONST BYTE*, INT, GpFillMode,
                                     GpPath **path);
etc...

Проблема в том, что GpStatus - это typedef для Status в GdiPlusGpStubs.h (заголовок C ++), а Status - это само перечисление, определенное в GdiPlusTypes.h (также заголовок C ++). Я попытался определить перечисление самостоятельно, но по какой-то причине компилятор не принял его!

Итак ... как точно использовать функции GDI + в C? Должен ли я просто загрузить gdiplus.dll динамически?

Ответы [ 2 ]

6 голосов
/ 28 февраля 2011

Проблема в том, что gdiplusflat.h действительно нужно еще много заголовочных файлов gdi * .h, включенных перед ним. Но многие из этих заголовочных файлов, которые имеют необходимые объявления typedef, на которые ссылается gdiplusflat.h, также содержат объявления "class" и другие ключевые слова C ++. Компилятор C выдаст ошибку, когда увидит эти строки.

У вас есть два варианта.

  1. Simple. Примите тот факт, что C ++ по сути является надмножеством C. Затем просто переименуйте ваш файл .c, который вы пытаетесь скомпилировать, чтобы иметь расширение .cpp. Ваш код на C будет скомпилирован как C ++, но это, скорее всего, не изменит строку кода, которую вы пишете. Затем #include gdiplus.h, прежде чем #include gdiplusflat.h

  2. Harder. зависит от определений typedef в других заголовочных файлах. Проблема в том, что многие из этих заголовочных файлов имеют определения «класса» и ключевые слова C ++, из-за которых компилятор C будет выдавать ошибку. Вам придется вручную перенести многие объявления C в свой собственный заголовочный файл, который включается до gdiplusflat.h. Вот моя слабая попытка. Это не совсем сделано. Получает половину ошибок компиляции. Но я слишком устал и просто выбрал вариант № 1. Вы могли бы закончить это, но вариант 1 выше намного проще.

х

enum Status
{
    Ok = 0,
    GenericError = 1,
    InvalidParameter = 2,
    OutOfMemory = 3,
    ObjectBusy = 4,
    InsufficientBuffer = 5,
    NotImplemented = 6,
    Win32Error = 7,
    WrongState = 8,
    Aborted = 9,
    FileNotFound = 10,
    ValueOverflow = 11,
    AccessDenied = 12,
    UnknownImageFormat = 13,
    FontFamilyNotFound = 14,
    FontStyleNotFound = 15,
    NotTrueTypeFont = 16,
    UnsupportedGdiplusVersion = 17,
    GdiplusNotInitialized = 18,
    PropertyNotFound = 19,
    PropertyNotSupported = 20,
#if (GDIPVER >= 0x0110)
    ProfileNotFound = 21,
#endif //(GDIPVER >= 0x0110)
};



typedef Status GpStatus;

enum FillMode
{
    FillModeAlternate,        // 0
    FillModeWinding           // 1
};

typedef FillMode GpFillMode;

struct GpPath {};

typedef float REAL;

struct GpPointF
{
    REAL x;
    REAL y;
};

struct GpPoint
{
    int x;
    int y;
};
#include <gdiplusflat.h>
3 голосов
/ 16 января 2014

Вы можете использовать Flat API из MSDN. Существует прямое преобразование из Flat API (C) в GDI + (C ++), я думаю, что это довольно просто.

P.S: Однако вы все равно можете использовать GDI прямо в C.

...