Мы пытаемся создать компонент библиотеки, который будет выполнять асинхронные вызовы.По разным причинам для этого необходим интерфейс, подобный C, поэтому мы предоставляем большой набор статических функций в качестве интерфейса к библиотеке.
Нам также нужно, чтобы пользователь имел контроль над памятью.Так что большинство функций выглядят примерно так:
int myLibFunction(void* data, size_t data_size);
Я пытаюсь заменить это на более умный объект Future, чтобы мы не использовали пустые указатели и чтобы доступ к даннымсинхронизируется между потоками.В идеале вызовы должны выглядеть примерно так:
Future<T> {
T m_data;
}
static int myLibDoJob1(Future<Func1Data>& data);
static int myLibDoJob2(Future<Func2Data>& data);
main()
{
Func1Data m_data;
Func2Data m_data2;
Future<Func1Data> future1(m_data);
Future<Func2Data> future2(m_data2);
int ret=0;
ret = myLibDoJob1(future1);
ret = myLibDoJob2(future2);
}
Это довольно чистый интерфейс, и интерфейс обеспечивает безопасность типов во время компиляции.Однако проблема у меня заключается в том, что я создаю очередь заданий для внутреннего выполнения.Однако из-за того, что Futures имеют разные размеры, я не могу создать из них очередь std: я надеялся, что смогу создать std :: queue с заданием Job, содержащим Future *, однако это недопустимо.
Я также пытался заставить Job содержать Future, где все классы данных также являются производными от ParentData, но безрезультатно.
Проблема очень похожа на проблему с контейнерами умных указателей.Из-за специфики команды, в которой я работаю, я не смогу выставить какие-либо дополнительные объекты за пределами библиотеки, и меня будут преследовать крикетной битой, если я сделаю Future полиморфным.
Важно, чтобы код на стороне пользователя в библиотеке контролировал, где на самом деле находятся данные.
С уважением, Iain