LINUX.ORG.RU

Помогите перенести код с Win на Linux


0

0

Добрый день всем! Я в Linux совсем новенькая, но мне дали задание по переносу кода с Win на Linux. Есть некая часть платформенно-зависимого кода. Хотелось бы, чтобы коллеги помогли, а то не знаю, куда копать. Надеюсь, что здесь есть люди, которые и в винде понимают и помогут перенести. Есть некий набор классов, которые мне нужно переписать под Linux.

1. Есть, например, класс CString (строка соответственно), но там везде используется TCHAR. Вопрос - есть ли под Linux какой-то подобный тип или нужно тупо самой его вводить?

#ifndef _TCHAR_DEFINED #if !__STDC__ typedef wchar_t TCHAR; #endif #define _TCHAR_DEFINED #endif

2. Также в коде используется макрос ASSERT из MFC. Я так понимаю, что его можно заменить на assert из CRT? Еще используется VERIFY из MFC. Тоже вопрос, чем его можно заменить? Аналогии в CRT что-то не вижу.

3. Есть ли в Linux аналог GetModuleFileName (известен HANDLE)?

4. va_list и иже с ним, я так понимаю, имеются?

5. Есть класс CMutex, который на самом деле внутри виндовая критическая секция. Соответственно, вопрос, есть ли в Linux аналог InitializeCriticalSection, DeleteCriticalSection, EnterCriticalSection, LeaveCriticalSection, TryEnterCriticalSection, структуры CRITICAL_SECTION? Желательно, без posix обойтись, если можно. До меня дошли слухи, что можно и без него.

6. Есть ли аналог MessageBox, CreateFile, CloseHandle, WriteFile, ReadFile, GetFileSize, SetFilePointer, MultiByteToWideChar (CP_ACP), WideCharToMultiByte, GetLocalTime?

7. Есть ли аналог ресурсов в файле, как в винде? И соответствено есть ли аналоги функций для работы с ресурсами FindResourceEx, SizeofResource, LoadResource, LockResource?

8. Есть ли аналоги QueryPerformanceCounter? Есть такой класс таймера - там этот вызов активно используется:

__int64 CTimer::m_frequency = CRLTimer::Init();

void CTimer::Start() { VERIFY(::QueryPerformanceCounter((LARGE_INTEGER*)&m_tStart)!=0); }

void CTimer::Stop() { VERIFY(::QueryPerformanceCounter((LARGE_INTEGER*)&m_tTime)!=0); m_tTime -= m_tStart; }

double CTimer::GetElapsedSeconds() { __int64 tTime; VERIFY(::QueryPerformanceCounter((LARGE_INTEGER*)&tTime)!=0); tTime -= m_tStart; return ((double)tTime/m_frequency); }

__int64 CTimer::Init() { VERIFY(::QueryPerformanceFrequency((LARGE_INTEGER*)&m_frequency)!=0); return m_frequency; }

Или, может, есть идеи, как его еще переписать, если в Linux нет чего-то подобного счетчикам производительности?

9. Есть ли вызовы, подобные InterlockedIncrement, InterlockedDecrement, lstrlen, функция типа _tcschr и иже с ними _t*?


Без POSIX только если использовать wine.

А вообще советую почитать "Advanced Programming in the UNIX® Environment" Стивенса.

Всё, что касается пользователького интерфейса - это к тулкитам, Qt или Gtk+.

Begemoth ★★★★★
()

прежде всего http://www.gnu.org/software/libc/manual/html_mono/libc.html
~~~
1. если TCHAR входит в стандарт, то он "есть и в линуксе", а если это такая реализация компилятора (borland cpp builder?), то наверное прийдётся самой реализовывать...

а вообще же, если код писать правильно, и пользоваться стандартными функциями, то проблем переносимости будет намного меньше

3. смотреть по созданию процессов по ссылке на верху

6. есть: ru.wikipedia.org/wiki/Gtk ru.wikipedia.org/wiki/Qt

7. нет

8. смотри ссылку наверху
~~~

windows - это жалкая, неудачная попытка уйти от xNIX идеологии и добавить простоту интерфейса для пользователя, в результате система нисколько не терпима к прицизиозным, ответственным задачам... поэтому программист должен писать для GNU/Linux, а затем портировать в windows, если подразумевается кроссплатформенность.

короче, тебе сначало нужно разобраться, что такое GNU/Linux и почему он такой какой он есть, а не такой совместимый с windows, и за тем уж переносить...

AGUtilities ★★★
()

Графику (всякие месседж боксы) ты так сразу не перенесешь. Придется делать какую то GUI обертку. Всей этой мутью с портированием мы в свое время занимались, и, впринципе, у нас сейчас весь вендовый код компилируется как есть. Так что все возможно.

CString замени на std::string. GetModuleFileName у тебя не будет. Впринципе может и можно похимичить, но я так сходу не скажу. CMutex можно переколбасить с pthreads. Ресурсы тебе не помогут, т.к. см. выше. С таймером хз. Но в конце концов можно всегда повеситься на gettimeofday и rdtsc :] MultiByteToWideChar итд можно написать с iconv. _t придется искать функциональную альтернативу.

vasily_pupkin ★★★★★
()

8. Performance counter'ы для *секундного* таймера - это кувалдой по микробам. Если коллбэка от таймера не надо, то gettimeofday, как уже советовали. Если надо, то читать про /dev/rtc и/или /dev/hpet.

9. Ещё бы сказала, что это за InterlockedIncrement (atomic_add?)...

mv ★★★★★
()

> CMutex ... Желательно, без posix обойтись, если можно. До меня дошли слухи, что можно и без него.

В boost::что-то есть кросплатформенные локи, может мьютексы.

З.Ы. Идея сделать открытую библиотечку для переноса с(++) кода с винды я думаю приходила в голову и раньше людям, странно будет если ее еще нет....

www_linux_org_ru ★★★★★
()
Ответ на: комментарий от AGUtilities

> как тут уже говорили - wine. но это, imho, от лукавого

Речь идет о не-вин-специфичных фенечках, типа открыть файл, мьютексы, ... ради которых линковать libwine -- явный overkill.

www_linux_org_ru ★★★★★
()

1. Сдаётся мне, что все _t* ф-ии придётся дефайнить как это сделано в MFC
2. ох не помню что делает VERIFY
3. сомневаюсь... lsof :)
4. уж va_list то есть
5. Для критич6еских секций и для многого другого, если без posix, можно заюзать Glib
6. GTK, fopen/fclose/fwrite, stat/fstat и тот же Glib придут на помощь
7. Ресурсы придумали проприерасты. Но в любом случае и Qt и GTK позволяют ембеддить те же картинки в виде кода
8. хз
9. найдутся

yoghurt ★★★★★
()
Ответ на: комментарий от vasily_pupkin

MultiByteToWideChar - это, я так понимаю, преобразования мультибайтной строки утф8 в широкую строку у мелкомягких?
Тогда в стандарте Си есть нормальная функция - mbstowcs.

dont
()

> Есть ли в Linux аналог GetModuleFileName (известен HANDLE)?

Можно сделать что то вроде такого:

int main(int argc, char *argv[]) {
   std::string path;
   char *p = (char*)malloc(MAX_PATH + 1);
   if(realpath(argv[0], p)) {
      path = p;
      size_t i = path.find_last_of('/');
      path.erase(i, path.length() - i);
      path += "/";
   }
   free((void*)p);

   return 0;
}

andreyu ★★★★★
()

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

Делай примерно так: компилируешь, смотришь ошибки, реализуешь по порядку ненайденные функции и т.д.

P.S. Судя по твоим вопросам - у тебя скилл по разработке в linux минимальный.

Esh ★★★★
()
Ответ на: комментарий от XJess

> Да, минимальный - я этого и не скрывала вообще-то.

Надеюсь кроме той моей фразы ты остальное прочитала.

Esh ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.