×
Мы обрабатываем cookies, чтобы сделать наш сайт удобнее и персонализированнее для вас. Подробнее: политика использования «cookies» и «политики конфиденциальности».

Для самостоятельной настройки ознакомьтесь с инструкцией

Дополнительные настройки cookies в браузерах

Файлы cookie автоматически загружаются в ваш браузер при посещении веб-сайта. У вас есть возможность управлять этими файлами. Если Вы не согласны с использованием файлов cookies, запретите их сохранение на своём устройстве, удалите уже имеющиеся файлы cookies через настройки браузера или прекратите использование сайта.

При отключении обработки cookie наш сайт продолжит функционировать, однако будут использоваться исключительно необходимые технические файлы, без которых работа ресурса невозможна.

Инструкция по отключению cookies
Принять
Настроить
Отклонить

ДОКУМЕНТАЦИЯ

Выберите версию, форк и язык для СУБД Digital Q.DataBase, чтобы прочитать или скачать всю документацию.
Техподдержка
Документация
Диасофт
Авторские права © 2016–2025 ООО "Диасофт Экосистема"
Скачать всю документацию:

4.3.13. C++ Приложения

4.3.13.1. Область видимости главных переменных
4.3.13.2. Разработка приложений на C++ с использованием внешнего модуля на языке C

Препроцессор ECPG имеет ограниченную поддержку приложений на языке C++. В данном разделе описаны некоторые ограничения.

Параметр ecpg препроцессор ECPG принимает входной файл, написанный на языке C (или аналогичном) и содержащий внедренные SQL-команды, преобразует внедренные SQL-команды в фрагменты кода на языке C и в конечном итоге генерирует .c файл. Объявления в заголовочных файлах для библиотечных функций, используемых фрагментами кода на языке C, которые ecpg создает препроцессор ECPG, обернуты в extern "C" { ... } блоки при использовании в среде C++, поэтому они должны корректно работать в C++.

В целом, однако, ecpg препроцессор поддерживает только язык C; он не обрабатывает специальный синтаксис и зарезервированные слова языка C++. Таким образом, некоторый код внедренного SQL, написанный в приложении на C++ с использованием специфичной для C++ функциональности, может быть обработан препроцессором некорректно или работать не так, как ожидалось.

Безопасный способ использования внедренного SQL в приложении на C++ заключается в сокрытии вызовов препроцессора ECPG в модуле на языке C, к которому приложение на C++ обращается для доступа к базе данных, с последующей компоновкой этого модуля с остальным кодом на C++. См. Раздел 4.3.13.2 об этом.

4.3.13.1. Область видимости главных переменных #

Данный ecpg препроцессор распознает область видимости переменных в языке C. В языке C это реализовано достаточно просто, так как область видимости переменной определяется блоком кода, в котором она объявлена. Однако в языке C++ обращение к переменным-членам класса выполняется в ином блоке кода, отличном от места их объявления, поэтому ecpg препроцессор не сможет корректно определить область видимости переменных-членов класса.

Например, в приведенном ниже случае ecpg препроцессор не сможет найти объявление переменной имя базы данных dbname в test методе, что приведет к ошибке.

class TestCpp
{
    EXEC SQL BEGIN DECLARE SECTION;
    char dbname[1024];
    EXEC SQL END DECLARE SECTION;

  public:
    TestCpp();
    void test();
    ~TestCpp();
};

TestCpp::TestCpp()
{
    EXEC SQL CONNECT TO testdb1;
    EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
}

void Test::test()
{
    EXEC SQL SELECT current_database() INTO :dbname;
    printf("current_database = %s\n", dbname);
}

TestCpp::~TestCpp()
{
    EXEC SQL DISCONNECT ALL;
}

Этот код приведет к возникновению ошибки следующего вида:

ecpg test_cpp.pgc
test_cpp.pgc:28: ERROR: variable "dbname" is not declared

Чтобы избежать данной проблемы с областью видимости, test функцию можно изменить, используя локальную переменную в качестве промежуточного хранилища. Однако такой подход является лишь неудачным обходным решением, так как он ухудшает читаемость кода и снижает производительность.

void TestCpp::test()
{
    EXEC SQL BEGIN DECLARE SECTION;
    char tmp[1024];
    EXEC SQL END DECLARE SECTION;

    EXEC SQL SELECT current_database() INTO :tmp;
    strlcpy(dbname, tmp, sizeof(tmp));

    printf("current_database = %s\n", dbname);
}

4.3.13.2. Разработка приложений на C++ с использованием внешнего модуля на языке C #

Если вы понимаете данные технические ограничения препроцессора ECPG при работе с C++, ecpg вы можете прийти к выводу, что компоновка объектных файлов C и C++ на этапе связывания для использования возможностей препроцессора ECPG в приложениях на C++ может быть более эффективным решением, чем написание команд внедренного SQL непосредственно в коде C++. В данном разделе на простом примере описывается способ отделения некоторых команд внедренного SQL от кода приложения на языке C++. В данном примере приложение реализовано на языке C++, в то время как язык C и препроцессор ECPG используются для установки соединения с сервером PostgreSQL.

Необходимо создать файлы трех типов: файл на языке C (*.pgc), заголовочный файл и файл на языке C++:

test_mod.pgc #

Модуль подпрограммы для выполнения команд SQL, внедренных в код на языке C. Он будет преобразован в test_mod.c препроцессором.

#include "test_mod.h"
#include 

void
db_connect()
{
    EXEC SQL CONNECT TO testdb1;
    EXEC SQL SELECT pg_catalog.set_config('search_path', '', false); EXEC SQL COMMIT;
}

void
db_test()
{
    EXEC SQL BEGIN DECLARE SECTION;
    char dbname[1024];
    EXEC SQL END DECLARE SECTION;

    EXEC SQL SELECT current_database() INTO :dbname;
    printf("current_database = %s\n", dbname);
}

void
db_disconnect()
{
    EXEC SQL DISCONNECT ALL;
}

test_mod.h #

Заголовочный файл, содержащий объявления функций модуля на языке C модуль (test_mod.pgc). Он подключается к файлу test_cpp.cpp. Данный файл должен содержать блок extern "C" вокруг объявлений функций, так как он будет компоноваться с модулем на языке C++.

#ifdef __cplusplus
extern "C" {
#endif

void db_connect();
void db_test();
void db_disconnect();

#ifdef __cplusplus
}
#endif

test_cpp.cpp #

Основной код приложения, включающий функцию была передана main и, в данном примере, класс C++.

#include "test_mod.h"

class TestCpp
{
  public:
    TestCpp();
    void test();
    ~TestCpp();
};

TestCpp::TestCpp()
{
    db_connect();
}

void
TestCpp::test()
{
    db_test();
}

TestCpp::~TestCpp()
{
    db_disconnect();
}

int
main(void)
{
    TestCpp *t = new TestCpp();

    t->test();
    return 0;
}

Для сборки приложения выполните следующие действия. Преобразуйте файл test_mod.pgc в test_mod.c путем запуска ecpgи создайте объектный файл test_mod.o посредством компиляции файла test_mod.c с помощью компилятора C:

ecpg -o test_mod.c test_mod.pgc
cc -c test_mod.c -o test_mod.o

Затем создайте объектный файл test_cpp.o посредством компиляции файла test_cpp.cpp с помощью компилятора C++:

c++ -c test_cpp.cpp -o test_cpp.o

Наконец, скомпонуйте эти объектные файлы test_cpp.o и test_mod.oв один исполняемый файл, используя драйвер компилятора C++:

c++ test_cpp.o test_mod.o -lecpg -o test_cpp

Наверх
свяжитесь
с нами
контакты
Для прямой связи с нами вы можете использовать контакты ниже, либо оставить заявку через форму обратной связи, и мы обязательно свяжемся с вами

*поля обязательные к заполнению