Получить Mono со встроенным Firebird, работающим в 64-битной среде Linux
Я пытаюсь получить встроенный Firebird 2.5 (64-битный) в Linux с работающим провайдером Firebird.net (FirebirdSql.Data.FirebirdClient).
Встроенная настройка FB для моей тестовой сборки работает на WinX86_64 с версией Windows Firebird Embedded. В Linux я использую основанные на FB встроенные файлы Linux версии, помещенные в каталог сборки:
- libfbembed.so *
- firebird.msg
- security2.fdb
- libicu *
- libib *
Установите "RootDirectory" в каталог сборки в firebird.conf. Установите переменные среды оболочки LD_LIBRARY_PATH и FIREBIRD в каталог сборки.
FbConnectionStringBuilder conn = new FbConnectionStringBuilder();
conn.Database = @"/home/dev/firebirdTest/1stDB.FDB";
conn.ServerType = FbServerType.Embedded;
conn.UserID = "SYSDBA";
conn.Password = "masterkey";
conn.Charset = "UTF8";
conn.DataSource = "localhost";
conn.ClientLibrary = "libfbembed.so";
string connStr = conn.ConnectionString;
var dbcon = new FbConnection(connStr);
FbConnection.CreateDatabase(connStr, pageSize: 8192, forcedWrites: true, overwrite: false);
dbcon = new FbConnection(connStr);
dbcon.Open();
что я делал раньше:
- Перенаправление клиентской библиотеки Firebird с помощью моно dllmap не работает. Решено путем явной установки ClientLib в коде C#.
- Ручное создание базы данных с isql на Linux работает.
- Создание базы данных по коду в Linux работает.
- поставщик Firebird .NET создает в режиме отладки FB_{sanitizedName}.dll и DynamicAssembly.dll
- провайдер.NET действительно молчит. Отладка была выполнена путем запуска сборки с помощью "strace mono {testAssembly.exe}" в Linux.
- FbConnection.CreateDatabase аварийно завершает работу с ошибкой ввода-вывода во время "open O_CREAT" (вызывая FbCreateDatabase), если размер страницы не равен 8192. Установка явного размера страницы в 8192 решает эту проблему.
Теперь я запускаю следующие ошибки (и застрял здесь на несколько дней...):
Открытие существующего файла базы данных (как в коде здесь), происходит сбой с:
FirebirdSql.Data.FirebirdClient.FbException: неверный дескриптор базы данных (без активного подключения) ---> неверный дескриптор базы данных (без активного подключения)
Что не так?
1 ответ
Я застрял с этой ошибкой тоже. FirebirdSql.Data.FirebirdClient.FbException: недопустимый дескриптор базы данных (без активного подключения). Попытки с FB 2.5.* И 3.0.0 совпадают. Также пытался использовать отладочные сборки FB. Логи не помогли.
Может, кто-то здесь знает, в чем проблема?
Прошло 3 года с момента первоначальной публикации, и я столкнулся с той же проблемой. У меня нет "ответа", но у меня есть объяснение. Похоже, что маршалинг объектов SafeHandle не полностью реализован в моно. Из их документации по SafeHandle: "Обратите внимание, что" ref SafeHandles "передает указатель на слот, содержащий ноль, в методы P/Invoked, а при возврате создается новый SafeHandle с возвращенным значением." Ref SafeHandles "на самом деле не делает получить исходное значение SafeHandle.handle."
Если вы посмотрите исходный код FirebirdClient в IFbClient, вы увидите, что объявления P/Invoke выглядят так:
IntPtr isc_detach_database(
[In, Out] IntPtr[] statusVector,
[MarshalAs(UnmanagedType.I4)] ref DatabaseHandle dbHandle);
DatabaseHandle является производным от SafeHandle, поэтому второй аргумент является аргументом "ref SafeHandle" и страдает от проблемы, указанной выше - он будет в основном передавать ноль, а не фактическое значение дескриптора.
Нет другого решения, кроме как (а) улучшить реализацию SafeHandle в моно или (б) переписать FirebirdClient, чтобы избежать использования SafeHandles.