CAD-страница НП | Статьи | English | Download

Н.Н.Полещук. Первичные рекомендации по переводу приложений с ObjectARX 2004-6 на ObjectARX 2007-8

Здесь мы обсуждаем некоторые проблемы, возникающие при переходе с ObjectARX 2006 (и 2004/2005) на ObjectARX 2007 (и 2008).

Основные отличия ARX-проекта 2004/2005/2006 от 2007

Самое главное: приложения для AutoCAD 2007 и выше должны поддерживать юникоды, т.е. каждая буква кодируется не одним байтом, как в обычной ANSI-кодировке, а двумя. Сформулируем самые очевидные отличия:

N Наименование AutoCAD 2004/2005/2006 AutoCAD 2007                  
1 Тип строковых данных char *
char []
wchar_t *
wchar_t []
2 Явно заданные строковые константы "Пример строки" L"Пример строки"
3 Функции, работающие со строками _itoa(), ... _itow(), ...

Однако есть еще много других, менее очевидных, отличий, которые выявляются при конкретной переделке программ под следующую версию. Часть из них указана в файле ObjectARX 2007\docs\acad_xmg.chm ("ObjectARX Migration Guide").

Рекомендации по подготовке исходных текстов программ ARX-приложений под AutoCAD 2004/2005/2006 и AutoCAD 2007

Исходные тексты желательно создавать в таком виде, чтобы их без изменений можно было включать в приложения под разные версии AutoCAD. Учитывая, что мастер ObjectARX в версиях от 2004 до 2007 создает заготовки проектов по одинаковому шаблону, можно писать программы в универсальной форме. Все отличия в версиях будут спрятаны в дополнительно подключаемых заголовочных файлах и библиотеках, которые, как правило, сохраняют свои названия от версии к версии. Теоретически можно создавать тексты, подходящие и для более ранних версий (2002, 2000i, 2000), но для них мастером ObjectARX используется другой шаблон, поэтому распространение текстов на эти версии здесь не рассматриваем (возможно, но сложнее).
Три базовых отличия приложений на C++ были названы выше. Далее следуют рекомендации по каждому из них.

Тип данных ACHAR

Этот тип объявлен в файле AdAChar.h версии ObjectARX 2006 следующим образом:

typedef char ACHAR;

В версии 2007 в одноименном файле описание типа ACHAR уже такое:

typedef wchar_t ACHAR;

Отсюда вывод: в обеих версиях вместо типов char и wchar_t удобно использовать в программе универсальный тип ACHAR, для чего в тексте должна быть инструкция:

#include "AdAChar.h"

Это обеспечит единообразие текста программ с декларацией типов строковых переменных, как для 2006, так и для 2007. Поэтому можно строить приложения для AutoCAD 2004/2005/2006 с помощью ObjectARX 2006 (необходимо, правда, убедиться в работоспособности ваших ARX-файлов в системе AutoCAD 2004/2005, если приложение должно работать и в них).
В ObjectARX 2005 файла AdAChar.h нет, а объявление типа ACHAR, аналогичное первому, можно найти в файле adesk.h. Если посмотреть внимательнее, то увидим, что в файле adesk.h ObjectARX версий 2006 и 2007 присутствует инструкция на включение файла AdAChar.h. Поэтому для общности правильнее подключать не AdAChar.h, а adesk.h:

#include "adesk.h"

Макросы из TCHAR.H

Файл tchar.h был включен фирмой Microsoft в Visual C++ для облегчения перевода приложений на работу с юникодами.
При наличии в тексте программы инструкции

#include <tchar.h>

для препроцессора, работающего перед компиляцией, становятся доступными макросы, описанные в этом заголовочном файле Visual C++.

Макрос _T

В первую очередь в tchar.h нам интересен макрос _T, который при задании инструкции препроцессора

#define _UNICODE

добавляет перед аргументом символ L (что как раз необходимо для явно заданных юникодовских строковых констант). В то же время если идентификатор _UNICODE не определен, то макрос _T ничего не делает (оставляет аргумент без изменений).

Пример:
acutPrintf(_T("Система проектирования, 2007 г."));

Справка. В Visual C++ 2005 по умолчанию идентификатор _UNICODE всегда определен.

Макросы строковых функций

В файле tchar.h описано большое количество макросов, соответствующих функциям, работающим со строками. Например:

Макрос Функция ANSI Функция Unicode
_itot _itoa _itow
_ttoi atoi _wtoi
_ttol atol _wtol
_tstof atof _wtof
_tcslen strlen wcslen
_tcscat strcat wcscat
_tcscpy strcpy wcscpy
_tcsncpy strncpy wcsncpy

Поэтому вместо строковых функций в универсальном тексте лучше применять макросы, которые преобразуются препроцессором в соответствующие имена функций (ANSI или Unicode).

Примечание 1. Некоторые из функций (например, strcat), в Visual C++ 2005 отнесены к устаревшим в связи с появлением безопасных аналогов (strcat_s).

Примечание 2. Многие функции Windows API на самом деле имеют два варианта ≈ для ANSI и Unicode, что отражается в самостоятельной подстановке компилятором в конце имени символов A или W. Например, MessageBoxA и MessageBoxW.

Инструкции препроцессора

Для устаревших функций и других случаев, когда недостаточно макросов из файла tchar.h, можно использовать инструкции предварительной обработки кода препроцессором. Куски текста исходного кода, которые должны по-разному выглядеть при поддержке юникодов и без таковой, формируются с помощью оператора #ifdef или оператора #ifndef. Пример:

#ifdef _UNICODE
_tcscat_s (s1, s2);
#else
_tcscat (s1, s2);
#endif

В этом примере в текст для AutoCAD 2007 (Visual C++ 2005) будет включена новая безопасная функция wcscat_s, а в текст для AutoCAD 2005 (Visual C++ 2002) - более старая функция strcat.
С помощью таких ветвлений можно учесть и особенности системы AutoCAD 2007 по сравнению с более ранними (например, в версии 2006 и раньше создавать сеть, а в версии 2007 и позже - строить поверхность).
Точно так же, но уже с помощью пользовательских идентификаторов для препроцессора можно делать ветвления для разных языковых версий (русский-английский и т.п.), а также для поддержки 64-разрядности.


CAD-страница НП | Статьи | English | Download