Получить 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.

Другие вопросы по тегам