Сча сам пробую колупаться. По идее там надо указать хидеры и сопоставить с .lib’ами откуда берутся импорты для dll. Потом посмотреть какую чехарду генерирует из крестов и править это регулярками и проч. (смотрю на то как сделан ChakraSharp) в итоге выкатывается шарповый класс со всеми обвязками.
В общем почти получилось. Собрал хидеры и либы сфинкса в кучу. Но при сборке ругается что не видил библиотек Windows Kits
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt\corecrt_wstdio.h(1348,29): error: no matching function for call to ‘__stdio_common_vswprintf’
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt\corecrt_wstdio.h(1366,16): error: no matching function for call to ‘_vscwprintf_l’
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt\corecrt_wstdio.h(1381,29): error: no matching function for call to ‘__stdio_common_vswprintf_p’
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt\corecrt_wstdio.h(1399,16): error: no matching function for call to ‘_vscwprintf_p_l’
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt\corecrt_wstdio.h(1457,19): error: no matching function for call to ‘__vswprintf_l’
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt\corecrt_wstdio.h(1477,19): error: no matching function for call to ‘_vswprintf_c_l’
C:\Program Files (x86)\Windows Kits\10\Include\10.0.17763.0\ucrt\corecrt_wstdio.h(1542,23): error: no matching function for call to ‘_vswprintf_s_l’
А как подключить по умолчанию не понял. Неужели все либы надо руками прописывать.
наоборот же вроде, библиотеки ругаются )
Точнее ошибки странные, там после например no matching function for call to ‘__stdio_common_vswprintf’
ничего больше нет в этой ошибке?
таких ошибок куча. Это копия ошибки.
Тут еще вот какая ошибка лезет:
Error parsing ‘C:\Delme\WindowsFormsApp1\src\sphinxbase\yin.h’
C:\Delme\WindowsFormsApp1\src\sphinxbase\yin.h(113,1): error: extraneous closing brace (’}’)
CppSharp has encountered an error while parsing code.
Вот сюда кидает:
Где должен этот дефайн определяться?? или не должен. В оригинальном проекте на сях проблем при сборке нету.
В дополнительных зависимостях в оригианльном проекте указана winmm.lib а тут куда ее впихнуть то?
я о том, что после no matching function for call to ‘__stdio_common_vswprintf’
обычно пишется причина, например, передали char
вместо wchar_t
потому что включен флаг о юникоде и вызывается W версия функции вместо A.
А это где? В VS Linker -> Input в настройках проекта.
Да не. Я так понимаю что я должен в параметры CppSharp задать эти зависимости.
При запуске генерации?
Тут есть пример https://github.com/mono/CppSharp/blob/master/docs/GeneratingBindings.md
void Setup(Driver driver)
{
var options = driver.Options;
options.GeneratorKind = GeneratorKind.CSharp;
var module = options.AddModule("Sample");
module.IncludeDirs.Add("C:\Sample\include");
module.Headers.Add("Sample.h");
module.LibraryDirs.Add("C:\Sample\lib");
module.Libraries.Add("Sample.lib");
}
public void Setup(Driver driver)
{
var options = driver.Options;
options.GeneratorKind = GeneratorKind.CSharp;
var module = options.AddModule("pocketsphinx");
module.IncludeDirs.Add(@"C:\Delme\WindowsFormsApp1\src");
module.IncludeDirs.Add(@"C:\Delme\WindowsFormsApp1\src\pocketsphinx");
module.IncludeDirs.Add(@"C:\Delme\WindowsFormsApp1\src\sphinxbase");
foreach (var file in Directory.GetFiles(@"C:\Delme\WindowsFormsApp1\src", "*.h", SearchOption.AllDirectories))
{
module.Headers.Add(file);
}
module.Defines.AddRange(new string[] {
"NDEBUG",
"_USRDLL",
"SPHINX_DLL",
"SPHINXBASE_EXPORTS",
"HAVE_CONFIG_H",
"_CRT_SECURE_NO_DEPRECATE"
});
AddLibraries(module, @"C:\Delme\WindowsFormsApp1\src\lib");
//AddLibraries(module, @"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\ucrt\x86");
//AddLibraries(module, @"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0\um\x86");
//AddLibraries(module, @"C:\Program Files (x86)\Windows Kits\10\Lib\10.0.17763.0");
}
это откуда? Вроде ж надо module.Libraries.Add
.
Моя функция которая добавляет папку и все либы из подпапок
Короче выкинул я эту CppSharp в помойку. Не вижу объективного смысла пользовать ее. Слишком много пытается навесить. С помощью классического DllImport натискал функций из либы, перенес структуры и все нормально заработало. Движок инициализировался успешно.
В чем преимущество CppSharp так и осталось загадкой.
Ну он по идее просто время экономит (и уменьшает риск ошибки при написании импортов), особенно если либа большая и в ней какие-то сложные структуры.
Там в примерах внизу огромные фреймворки типа Qt, запаришься же при каждом релизе искать все изменения и переписывать.
Попробую завтра на нескольких либах.
Попробовал пока на своей небольшой библиотеке с C API, статически собранной в VS 2017.
Особых проблем с запуском не было: поставил CppSharp из NuGet в проект, адаптировал пример с https://github.com/mono/CppSharp/blob/master/docs/GeneratingBindings.md, получил Sample.cs
в bin
.
using CppSharp;
using CppSharp.AST;
using CppSharp.Generators;
namespace CppSharpExample
{
class SimpleCBindingGenerator : ILibrary
{
public void Setup(Driver driver)
{
var options = driver.Options;
options.GeneratorKind = GeneratorKind.CSharp;
var module = options.AddModule("Sample");
module.IncludeDirs.Add(@"C:\Users\Alex\Downloads\libmy\src\libmy");
module.Headers.Add("libmy.h");
module.LibraryDirs.Add(@"C:\Users\Alex\Downloads\libmy\dll\x64");
module.Libraries.Add("libmy.lib");
}
public void SetupPasses(Driver driver)
{
}
public void Preprocess(Driver driver, ASTContext ctx)
{
}
public void Postprocess(Driver driver, ASTContext ctx)
{
}
}
class Program
{
static void Main(string[] args)
{
ConsoleDriver.Run(new SimpleCBindingGenerator());
}
}
}
LLVM там нужен только для сборки CppSharp из исходников или и для использования тоже? У меня он уже был установлен через Chocolatey.
Была небольшая сложность с тем, что оно не понимало uint8_t
, uint64_t
, но это видимо моя недоработка, заработало после добавления #include <cstdint>
.
Сгенерированный код получился сложноватый, например, какой-то большой класс вместо просто struct
с [StructLayoutAttribute(LayoutKind.Sequential)]
.
У всех импортированных функций добавлен EntryPoint
. Насколько я знаю, это нужно для C++ классов и т.п., а для обычных C функций можно и не добавлять если имя то же.
Еще сами импорты в __Internal
и вызываются в функциях-обертках. Во многих просто вызов, но в некоторых например null
колбэки конвертируются в IntPtr.Zero
. Я сам так не делал, не знаю нужно ли.
Как я понял, там много возможностей менять вывод через обход дерева (AST) в Passes
и т.п. и опции, так что наверно можно упростить если надо.
В целом конечно для просто импорта пары функций в проекте можно не брать CppSharp, а вот если делать и поддерживать полноценные биндинги для какой-то большой библиотеки, то уже есть смысл автоматизировать.
Примерно как со сборкой/деплоем проекта, настройкой серверов. Для экспериментов и т.п. можно и просто в консоли пару раз команды повводить, а вот если нормально делать надолго, то лучше разобраться с системами сборки, деплоя и прочей автоматизацией.
Для маленьких проектов да. а вот для сфинкса и сфинспокет??
Ну его же даже для Qt и других больших проектов используют https://gitlab.com/ddobrev/QtSharp/blob/master/QtSharp/QtSharp.cs
А Сфинкс разве сам не предоставляет биндинги для C#?
https://sourceforge.net/p/cmusphinx/discussion/help/thread/fb985d4d/
Не нашел ничего полезного по ссылке.
Там ссылка на https://github.com/cmusphinx/pocketsphinx/blob/master/swig/csharp, где вроде бы лежит Makefile генерирующий C# биндинги через Swig (что-то типа CppSharp, но не только для C# https://github.com/mono/CppSharp/wiki/Users-Manual#why-reinvent-the-wheel).
Не знаю запускает ли VS на винде этот Makefile, если проект уже собран я бы для начала посмотрел поиском нет ли где-то *.cs файлов.
По сути не актуально … я руками прибиндил нужный функционал.
Студия мэкйфайл не запускает … его видимо через смэйк надо собирать.
Парни, ну вы и извращенцы. Я конечно понимаю и поддерживаю мнение - Все программисты ленивые и не хотят тратить свое время на переделку кода, даже собственного. Но иногда быстрее написать свое новое, нежели копать чужое или свое старое.
Или не прав, и не то понял?
Так смотря что.
Биндинги библиотеки для разных языков вполне нормальная вещь.
У CppSharp в примерах использования всякие огромные проекты типа Qt, ffmpeg.
Запаришься такое переписывать + всё рано может потребоваться писать их на С++ для производительности и т.д., а для основного своего проекта наоборот С++ может быть не лучшим выбором (время разработки, …).