LINUX.ORG.RU

C & C++


0

0

Имеется библиотека на C++ (adplug) , необходимо написать программу на C, использующую эту библиотеку. Основной фрагмент кода выглядит следующим образом:

bool play(const char *filename, const char *output)
{
CEmuopl opl(RATE, BIT16, STEREO);
CPlayer *p = CAdPlug::factory(filename, &opl);
FILE *f;
short buf[BUFSIZE];
unsigned long towrite, write;

if(!p) return false; // File couldn't be loaded

f = fopen(output, "wb");
while(p->update())
for(towrite = RATE / p->getrefresh(); towrite; towrite -= write) {
write = (towrite > BUFSIZE ? BUFSIZE : towrite);
opl.update(buf, write);
fwrite(buf, write, 2, f);
}

fclose(f);
return true;
}

Вопрос можно ли это сделать, или придеться править adplug.
Вопрос конечно глупый, но я раньше с такой ситуацией не сталкивался.

★★

Да, придётся или править adplug или (лучше) писать отдельную
"прослойку" для adplug.

Для того, чтобы функции, определённые в C++, можно было вызывать из C,
надо их объявлять как "extern C". Например:

extern "C" void * EmuOpl_New (int param1, int param2, int param3)
{
  return new CEmuopl(param1, param2, param3);
}

extern "C" void * Player_factory (const char *filename, void *opl)
{
  return CAdPlug::factory(filename, opl);  
}

Заголовки таких должны быть в C-style, т.е. не содержать имён классов
(разве что имена C-структур).
Кроме того, лучше ловить внутри этих функций C++ exceptions, чтобы
потом передать их в C. В простейшем варианте (без диагностики) это будет выглядеть так:

extern "C" void * Player_factory (const char *filename, void *opl)
{
  CPlayer *result;
  try
  {
    result = CAdPlug::factory(filename, (CEmuopl *)opl);
  }
  catch (...)
  {
    return NULL;
  }
  return result;
}

ringill
()
Ответ на: комментарий от ringill

>Да, придётся или править adplug или (лучше) писать отдельную "прослойку" для adplug.

Теперь не знаю, что и делать. Была идея написать демуксеры к mplayer для libtimidity, libmodplug и adplug. Первые два я написал без проблем,а с adplug такой гемор получается. В принципе мне он особо не нужен, просто хотел написать за компанию. Сегодня вечером подумаю, прослойку сделать конечно не сложно, но для проигрывания форматов которые не особо распространены ставить две либы, это слишком. К тому же прослойку надо оформлять как отдельный проект, а это как то лениво.

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