Я планирую кодировать библиотеку, которая должна быть применимой большим количеством людей в на широком спектре платформ. Что я должен рассмотреть для разработки его право? Для создания это подвергает сомнению более конкретный, существует четыре "дополнительных вопроса" в конце.
Рассматривая все известные требования и детали, я пришел к заключению, что библиотека, записанная в C или C++, была способом пойти. Я думаю, что основное использование моей библиотеки будет в программах, записанных в C, C++ и Java SE, но я могу также думать о причинах использовать его от ME Java, PHP.NET, Objective C, Python, Ruby, документов на получение удара, и т.д. Возможно, я не могу быть нацелен на всех них, но если это будет возможно, то я сделаю это.
Это было очень для описания полной цели моей библиотеки здесь, но существуют некоторые аспекты, которые могли бы быть важны для этого вопроса:
Конечно, ответы приветствуются, неважно, если они удовлетворяют мои конкретные требования, или если они отвечают на вопрос общим способом, который имеет значение для более широкой аудитории!
Таким образом, вот некоторые мои предположения и заключения, которые я собрал в прошлых месяцах:
В основном верно. Прямой процедурный интерфейс - лучший. (что не совсем то же самое, что C btw(**), но достаточно близко)
I интерфейс DLLs много(*), как с открытым исходным кодом, так и с коммерческим, поэтому вот некоторые моменты, которые я помню из повседневной практики, обратите внимание, что это более рекомендуемые области для исследования, а не кардинальные истины:
(**) Это связано с тем, что то, что означает "C", все еще зависит от используемого компилятора Си, особенно если нет реальной универсальной системы ABI. Подумайте о таких вещах, как:
===== автоматические преобразования заголовков ====
Хотя я не так хорошо знаю SWIG, я знаю и использую некоторые специфические для delphi заголовочные утилиты( h2pas, Darth/headconv и т.д.)
Однако я никогда не использую их в полностью автоматическом режиме, т.к. чаще всего не выходит отстойно. Комментарии меняются строкой или удаляются, и форматирование не сохраняется.
Обычно я делаю небольшой скрипт (в Pascal, но можно использовать что угодно с приличной поддержкой строк), который разбивает заголовок вверх, а затем пробую инструмент на относительно однородных частях (например, только структуры, или только определения и т.д.)
Затем я проверяю, нравится ли мне автоматический вывод преобразования, и либо использую его, либо пытаюсь сделать конкретный конвертер сам. Так как это для подмножества (например, только структуры), то часто это намного проще, чем сделать полный конвертер заголовков. Конечно, это немного зависит от того, что моя цель. (красивые, читаемые заголовки или быстро и грязно). На каждом шаге я могу сделать несколько замен (с помощью sed или редактора).
Самая сложная схема, которую я делал для заголовков Winapi commctrl и ActiveX/comctl. Там я объединил IDL и заголовок C (IDL для интерфейсов, которые представляют собой кучу недоступных макросов на C, заголовок C для остальных), и умудрился набрать макросы примерно на 80% (путем возврата шрифтов в макросах sendmessage обратно к макро-декларации, с разумными (wparam, lparam, lresult) значениями по умолчанию)
Полуавтоматический способ имеет недостаток в том, что порядок деклараций разный (e. g. сначала константы, затем структуры, затем объявления функций), что иногда делает обслуживание болезненным. Поэтому я всегда сохраняю оригинальные заголовки/dk для сравнения с.
Проект преобразования Jedi winapi может иметь больше информации, они перевели примерно половину заголовков окон в Delphi, и таким образом имеют огромный опыт.
.Не знаю, но если это для Windows, то вы можете попробовать либо прямой C-подобный API (похожий на WINAPI), либо упаковать свой код как COM-компонент: потому что я догадываюсь, что языки программирования могут захотеть иметь возможность вызывать Windows API, и/или использовать COM-объекты.
.Что касается автоматической генерации оберток, рассмотрим возможность использования SWIG. Для Java это сделает всю работу JNI. Кроме того, он способен корректно переводить сложные OO-C++-интерфейсы (при условии, что вы будете следовать некоторым основным рекомендациям, т.е. не будете использовать вложенные классы, не будете переусердствовать с шаблонами, плюс те, которые упомянул Марко ван де Воорт)
.NestedVM, на мой взгляд, будет медленнее, чем чистая Java, из-за проверки границ массива на int[][], представляющей память виртуальной машины MIPS. Это такая хорошая концепция , но сейчас она может работать недостаточно хорошо (пока производители телефонов не добавят поддержку NestedVM (если они это сделают!), большинство вещей пока будут SLOW, n'est-ce pas)? В то время как он может быть в состоянии распаковать JPEG без ошибок, скорость не имеет большого значения! :)
Больше ничего из того, что вы написали, не означает, что это правильно или неправильно! Принципы звучат (в основном, просто слушая выбор слов и языка, если быть честным) как примерно стандартная лучшая практика, но я не продумал детали всего, что вы сказали. Как вы сами сказали, это действительно должно быть несколько вопросов. Но, конечно, делать такие вещи нелегко автоматически только потому, что вы исправлены, возможно, на архитектуре, немного отличающейся от последней кодовой базы, над которой вы работали...! ;)
Мои мысли:
Все ваши комментарии по совместимости интерфейса C звучат для меня разумно, в общем-то, лучшая практика, за исключением того, что вы, кажется, неправильно обращаетесь к политике управления памятью - некоторые предложения немного двусмысленны/ расплывчаты/неправильно звучали. Дизайн управления памятью будет в значительной степени определяться шаблонами доступа, сделанными в вашем приложении, а не функциональностью как таковой. Я уверен, что вы внимательно изучите попытки других сделать портативные интерфейсы, такие как стандартный ANSI C API, Unix API, Win32 API, Cocoa, J2SE и т.д.
Если бы это был я, я бы написал библиотеку в тщательно отобранном подмножестве общих элементов обычной Java и Java виртуальной машины Davlik, а также написал бы свой собственный пользовательский парсер, который транслирует код на C для платформ, поддерживающих C, что, конечно же, было бы большинством из них. Я бы посоветовал ограничиться только типами данных различного размера - интами, булами, строками, словарями и массивами - и аккуратно использовать их, что поможет в кроссплатформенных вопросах, не влияя на производительность большую часть времени
.ваши предположения кажутся нормальными, но я вижу впереди неприятности, большую часть которых вы уже заметили в своих предположениях. Как вы сказали, на самом деле вы не можете экспортировать классы и методы на языке c++, вам потребуется функциональный интерфейс на языке c. Какой бы фасад вы ни строили вокруг этого, он останется интерфейсом, основанным на функциях.
Основная проблема, которую я вижу в этом, заключается в том, что люди выбирают конкретный язык и время его работы, потому что их образ мышления (функциональный или объектно-ориентированный) или проблема, к которой они обращаются (веб-программирование, базы данных...), так или иначе соответствует этому языку. Библиотека, реализованная на языке c, вероятно, никогда не будет похожа на библиотеки, к которым они привыкли, если только они сами не программируют на c. Лично я всегда предпочитал бы библиотеку, которая "чувствует себя как питон", когда я использую питон, и библиотеку, которая чувствует себя как java, когда я использую Java EE, хотя я знаю c и c++.
Так что ваши усилия могут быть малополезны (кроме как ваш опыт), потому что люди, вероятно, захотят придерживаться своего мышления, и вместо того, чтобы использовать библиотеку, которая делает работу, но не подходит.
Я также опасаюсь, что желаемая переносимость серьезно затруднит разработку. Просто подумайте о необходимых бесконечных настройках сборки, и тесты для этого. Я работал над проектом, который пытался поддерживать совместимость для 5 операционных систем (все posix-подобные, но всё же) и около 10 компиляторов, сборки были кошмаром для тестирования и сопровождения.
.Думай C, больше ничего. C - один из самых популярных языков программирования. Он широко используется на многих различных программных платформах, а архитектур компьютеров, для которых не существует компилятора Си, немного. Все популярные языки высокого уровня предоставляют интерфейс к Си. Это делает вашу библиотеку доступной практически со всех существующих платформ. Не беспокойтесь слишком сильно об обеспечении объектно-ориентированного интерфейса. После того, как библиотека сделана на Си, ООП, функциональный или любой другой стиль интерфейса может быть создан на соответствующих клиентских языках. Никакой другой язык системного программирования не даст вам гибкости и переносимости Си.
.Дайте ему XML-интерфейс, переданный в качестве параметра и возвращающий значение или в виде файлов с помощью вызова командной строки. Это может показаться не таким прямым, как обычный интерфейс функции, но это наиболее практичный способ получить доступ к исполняемому файлу, например, с Java.
.