#c #linker #d #ncurses #gdc
#c #компоновщик #d #ncurses #gdc
Вопрос:
Я пытаюсь научить себя искусственному интеллекту, используя нейронные сети. Короче говоря, я хотел создать простую графику, которая отображала бы то, что происходит в моей программе, используя ncurses. Учебное пособие, которое я использую, находится здесь .
У меня сложилось впечатление, что D совместим с C, и теоретически я мог бы относительно легко вызывать функции C.
Я считаю, что это не так. Я относительно начинающий программист, поэтому даже упрощенные объяснения немного выше моей головы. Я нашел это здесь.
D разработан так, чтобы удобно сочетаться с компилятором C для целевой системы. D компенсирует отсутствие собственной виртуальной машины, полагаясь на библиотеку времени выполнения C целевой среды. Было бы бессмысленно пытаться переносить на D или писать D-оболочки для широкого спектра доступных C API. Насколько проще просто вызвать их напрямую.
Это делается путем сопоставления типов данных компилятора C, макетов и последовательностей вызова / возврата функций.
Звучит замечательно. Немного выше моей головы. Я протестировал и получил простую работающую программу на C:
#include <curses.h>
int main(void) {
int ch;
initscr();
noecho();
cbreak();
printw("Hit Ctrl C to exit ...nn");
for (;;) {
ch = getch();
printw("Value of char: %d (x)n", ch, ch);
}
endwin();
return 0;
}
бесстыдно скопировано и вставлено из другого вопроса на SO.
По крайней мере, я сделал свою домашнюю работу.
Я попробовал в основном то же самое из простой общей программы. Я получил эту ошибку:
Error: module curses is in file 'curses.d' which cannot be read
Я абсолютно уверен, что пытаюсь сделать что-то действительно глупое.
Есть ли простой способ использовать ncurses в общей программе?
Я работаю без сна и кофеина, поэтому, пожалуйста, будьте осторожны! Даже ссылка на веб-сайт была бы очень признательна!
Я, вероятно, не включил все, что должен был иметь, так что АМА.
И не стесняйтесь оскорблять мой интеллект.
Комментарии:
1. Хорошо, итак, там есть мой комментарий о том, как D должен просто иметь возможность вызывать C, а затем снова на том же сайте утверждается, что вам придется переписать файлы .h в файлы .d . Это, по-видимому, довольно большая разница… Я склоняюсь ко второму, поскольку существует специальный инструмент Windows, который должен помочь автоматизировать процесс перевода файлов заголовков. как это называется. К сожалению, это только для Windows. Я начинаю понимать, насколько раздроблено сообщество D на самом деле…
2. хорошо, значит, можно связать D с библиотекой C. При условии, что вы случайно не назвали функции одинаково. (это был main(). facepalm). проблема в том, что вам все еще нужно преобразовать файл заголовка… Таким образом, технически можно вызывать функции C «легко» и без необходимости прибегать к оболочке. Но они не учитывают, что вам нужно преобразовать файл .h в файл .d, поскольку D не реализует CPP. Отлично. Вы видели файл .h, который я хочу преобразовать? это буквально ничего, кроме тысячи строк #ifndefs и #Pragmas .
3. Я бы не сказал, что сложность скрыта, она просто не выражается больше, чем необходимость конвертировать .h в .d, что, как знают те, кто знаком с C, будет непросто. И ncurses — это в значительной степени библиотека макросов, как вы, наверное, заметили. Вы можете запустить CPP для файла и заставить его выводить C, который намного проще преобразовать, но все равно может быть неправильным. В любом случае, хорошая работа.
4. О, я заметил. Я определенно заметил. = P Знаете ли вы, как заставить gcc выводить это? Я перепробовал кучу вариантов, но в основном я получаю объектный код или что-то нечитаемое .. забавная вещь, которую я нашел в источнике ncurses: // vile:cppmode
Ответ №1:
Хорошо, примерно через 8 часов копания в этом дерьме я определил, что действительно возможно вызывать функции C изначально.
ОДНАКО также указано, что «Было бы бессмысленно пытаться переносить на D или писать D-оболочки для широкого спектра доступных C API. Насколько проще просто вызвать их напрямую. «
Да, я собираюсь вызвать BS по этому вопросу. Вам нужно выполнить порт на D. Разве это не считается переносом, когда вы переходите от файла предварительной обработки .h с поддержкой макросов к файлу .d? Это определенно нетривиально. Поэтому, на мой взгляд, они намеренно не учитывают сложную часть и пытаются сделать так, чтобы она выглядела лучше, чем есть на самом деле.
На случай, если кому-то интересно, есть ли у вас C api, который вы хотели бы вызвать в своем коде D: возьмите файл заголовка и попытайтесь преобразовать его во что-то, что D может прочитать. Затем просто скомпилируйте свой код, импортируйте свой новый файл .d и свяжите его с тем, с чем вы взаимодействуете. Если вы все сделали правильно, это сработает, и теперь у вас будет много утечек памяти.
На мой взгляд, если вам не нужна вся библиотека, избавьте себя от головной боли и просто привяжите небольшую оболочку C к вашему общему коду. Вы получаете только то, что вам нужно, и у вас есть дополнительное преимущество в том, что вы можете переименовывать материал во что хотите.
Существует несколько проектов, помогающих автоматизировать процесс перевода заголовочных файлов. dtoh только для Windows и bcd, который находится в dsource. bcd также включает в себя привязки для проклятий! они перечислены только как альфа-версии, но, похоже, они работают. Я пытаюсь вызвать их файл curses.d из моего основного файла.d, и я получаю:
main.d:13: Error: cannot implicitly convert expression ("ype any character to see it in boldx0a") of type string to char[]
main.d:15: Error: function aphrodite.curses.printw (char*,...) is not callable using argument types (char[])
main.d:15: Error: cannot implicitly convert expression (stuff) of type char[] to char*
main.d:20: Error: function aphrodite.curses.printw (char*,...) is not callable using argument types (string)
main.d:20: Error: cannot implicitly convert expression ("F1 Key pressed") of type string to char*
main.d:26: Error: function aphrodite.curses.printw (char*,...) is not callable using argument types (string)
main.d:26: Error: cannot implicitly convert expression ("The pressed key is ") of type string to char*
main.d:28: Error: function aphrodite.curses.printw (char*,...) is not callable using argument types (string,int)
main.d:28: Error: cannot implicitly convert expression ("%c") of type string to char*
итак, моя проблема заключается в том, как C обрабатывает строки и как D обрабатывает строки. Они не совпадают, и мои крайне ограниченные знания C не говорят мне, как это исправить.
К счастью, несмотря на всю антидокументацию о вызове функций C, существует довольно много информации о том, как общие типы преобразуются в типы C.
Я искренне надеюсь, что кто-то найдет это полезным где-нибудь в будущем.
Комментарии:
1. Я «исправил» проблему со строковыми символами *, просто удалив их и решив исправить это, когда он будет правильно компилироваться и связываться. Итак, теперь моя самая большая проблема заключается в том, что я получаю эту ошибку компоновщика:/usr/bin/ld: stdscr: ссылка на TLS в main.o не соответствует определению, отличному от TLS, в разделе /usr/lib32/libcurses.so .bss /usr/lib32/libcurses.so: не удалось прочитать символы: плохозначение collect2: ld вернуло 1 статус выхода, теперь мне просто нужно это исправить..
2. хорошо, проблема с TLS вызвана d2. Во имя упрощения потоковой обработки они по умолчанию изменили все переменные на локальное хранилище потоков, поэтому я бы попросил вас изменить все без гарантии, что это решит мои проблемы…
3. Что касается переноса с C на D: то, что отвергается как бессмысленное, — это перенос кода, отличного от заголовка. {, полу-, не-} автоматизируемая задача генерации привязок для работы с компилятором D — это другая (и намного более простая) задача.
4. Теперь я это понимаю, но, как вы можете видеть из моего вопроса, я действительно не имел ни малейшего представления о том, что я делаю. Отсутствие документации меня расстроило, поэтому большая часть того, что я сказал, должна была быть «gr! я не понимаю! «В документе о D-Programming_Language было не очень понятно, о чем идет речь, по крайней мере, с точки зрения того, у кого мало опыта в этих вопросах. Но, вероятно, это все равно не было написано с учетом моего уровня опыта. Если подумать, теперь, когда я знаю то, что знаю, это имеет гораздо больше смысла. = P
Ответ №2:
Хорошо, я чувствую, что немного спамил, но я надеюсь, что вся информация будет полезна в будущем.
Я нашел название проекта ycurses. Я обнаружил, что проблема с TLS специфична для D2. Я изменил файлы для работы с D2. dmd, gdc, все работает. Наконец-то у меня есть ncurses, использующие D! Просто потребовались долгие выходные марафонского кодирования и исследований.
Поскольку код, который я нашел, устарел и, похоже, заброшен, я теперь размещаю его на github
Хотя в коде указано, что он будет работать с Tango, ЭТО НЕ ТАК. Я, вероятно, исправлю это как-нибудь на этой неделе.
В код включен небольшой приятный учебник, а также инструкция по созданию ссылок. Приветствую вас. Я внезапно чувствую себя очень совершенным.
Комментарии:
1. Печально, что вам пришлось пройти через столько трудностей во время первой пробы D. Видите ли, вызов кода C из D тривиален, он совсем не подходит для новичков, поскольку включает в себя множество сложных тем. Понимание ABI и возможность смешивать GC- и не-GC-код, по крайней мере. И это определенно проще по сравнению с большинством других языков.
2. Это правда, большинство моих трудностей проистекало из моего глубокого незнания всего, что связано с программированием. Надеюсь, я включил достаточно информации и ссылок, чтобы другие новички могли использовать мой опыт для обучения. Я не думаю, что это грустно, так как D заставил меня узнать за выходные больше, чем я узнал за два года занятий по программированию в университете. Я ни о чем не жалею.
Ответ №3:
Хорошо, есть порт curses.d? Я не знаю, как это назвать.. Он находится здесь .
Он по-прежнему требует, чтобы вы связывались с библиотекой ncurses, но он отлично работает, если вы компилируете с помощью компилятора d1 dmd. который кажется бесполезным в моем текущем проекте, поэтому мне нужно либо перенести файлы на d2 (неплохая идея, этот проект давно заброшен), либо посмотреть, есть ли способ связать файлы компиляции d1, скомпилированные файлы d2 и C. Мне кажется, что эточтобы быть прямым, но я также думал, что ссылка на C будет простой.
Итак, после нескольких дней и в основном тестов в стиле проб и ошибок с использованием файлов 7-летней давности, извлеченных из Интернета, я, наконец, получил простой мир hellp, скомпилированный с использованием библиотеки curses.
Я настоятельно рассматриваю возможность переноса файлов dcurses на D2 и размещения их самостоятельно… Я просто хотел бы, чтобы у меня было больше опыта в подобных вещах…
Ответ №4:
Могу ли я предложить взглянуть на Python? Я знаю, что это не D и это совершенно другой язык, но если ваша цель — изучить AI и не настаивать на использовании D, тогда Python очень хорош. Это позволит вам делать то, что вы обычно делаете в D, в 1/10 случаев. ncurses в Python — это простота. Я думаю, что был какой-то парень, который написал игру для тетриса примерно в 55 строк (что является стандартным).
Комментарии:
1. да, но python также выполняется примерно в 20 раз медленнее (по некоторым оценкам) Если я хочу написать что-то большое или требующее больших вычислительных ресурсов, это замедлит меня. Плюс я уже (вроде) знаю python. = P
2. Да, вы должны выполнить этот вызов. Если время выполнения программы на D / C составляет 0,01 с, то замедление в 20 раз не так уж и плохо. Даже если выполнение на C занимает 30 секунд, а на python 10 минут, оно все равно может стоить того, если позволит вам быстро написать то, что вы хотите. Еще одна вещь, которую нужно использовать, это (конечно) Matlab / Octave. Имейте в виду, что C / C / D — это то, что я называю дорогими языками — их следует использовать, только если вы не можете этого избежать, потому что вся их производительность зависит от скорости разработки. Для прототипирования / изучения Python / Matlab (я думаю) подойдет.
3. Очень верно, очень верно. Используйте лучший инструмент для работы.
4. Вы также можете взглянуть на семейство языков lisp. Он прост в использовании, как python, но работает намного, намного быстрее. Однако его библиотека далека от библиотеки python.