|
Форум
|
Catnip |
18.03.09, 12:11 |
|
Как использовать RCOFXRu.dll со сборкой .net? |
|
Здравствуйте.
Мои попытки прицепить RCO к .net-сборке методом проб и ошибок не увенчались успхом. Подскажите пожалуйста, где можно прочитать про использование вашего продукта с .net 3.5? |
|
|
Михаил Машкович |
30.03.09, 11:45 |
|
re: Как использовать RCOFXRu.dll со сборкой .net? |
|
Добрый день!
С помощью функицональности PInvoke. Как-то так: // менеджер загрузки внешних ресурсов, // нужен для инициализации библиотеки namespace RCO.FactExtractor.Demo.FX { using System.Runtime.InteropServices; using System; using System.Text;
[ComVisible(true)] [StructLayout(LayoutKind.Sequential)] public struct FX_FILE_RESOURCE_MANAGER { [MarshalAs(UnmanagedType.FunctionPtr)] public OpenResourceDelegate OpenResource; [MarshalAs(UnmanagedType.FunctionPtr)] public CloseResourceDelegate CloseResource; [MarshalAs(UnmanagedType.FunctionPtr)] public ReadResourceDelegate ReadResource; }
//FX_RESOURCE_HANDLE OpenResource(const wchar_t* szResourceId, const wchar_t* pszRusourceType) public delegate IntPtr OpenResourceDelegate( [MarshalAs(UnmanagedType.LPWStr)] StringBuilder szResourceId); //void CloseResource (FX_RESOURCE_HANDLE hResource) public delegate void CloseResourceDelegate(IntPtr hResource); //bool ReadResource (FX_RESOURCE_HANDLE hResource, void* pBuffer, unsigned long ulNumberOfBytesToRead, unsigned long* pulNumberOfBytesRead) public delegate bool ReadResourceDelegate(IntPtr hResource ,IntPtr pBuffer ,UInt32 ulNumberOfBytesToRead ,ref UInt32 pulNumberOfBytesRead); } |
|
|
Михаил Машкович |
30.03.09, 11:46 |
|
re: re: Как использовать RCOFXRu.dll со сборкой .net? |
|
// импорт функций namespace RCO.FactExtractor.Demo.FX { using System; using System.Runtime.InteropServices; using System.Security; using System.Text;
class FXAPI { internal const string DllPath = "RCOFXRu.dll";
//_FXAPI(FX_ERROR) FXCreateContext(const wchar_t* szConfig, FX_RESOURCE_MANAGER* pResManager, FX_HANDLE* pHandle); [SuppressUnmanagedCodeSecurity] [DllImport(DllPath ,CallingConvention = CallingConvention.StdCall ,CharSet = CharSet.Unicode ,SetLastError = true)] public extern static FX_ERROR FXCreateContext( string szConfig ,ref IntPtr mngr ,out IntPtr context);
//_FXAPI(FX_ERROR) FXDestroyContext(FX_HANDLE ptrContext); [DllImport(DllPath ,CallingConvention = CallingConvention.StdCall ,CharSet = CharSet.Unicode ,SetLastError = true)] public extern static int FXDestroyContext(IntPtr hContext);
//FX_ERROR __stdcall FXProcessText(FX_HANDLE ptrContext, const wchar_t* szText, const wchar_t* szTextID, FX_TEXT_FORMAT eFormat, FX_HANDLE* phResult) [DllImport(DllPath ,CallingConvention = CallingConvention.StdCall ,CharSet = CharSet.Unicode ,SetLastError = true)] public extern static FX_ERROR FXProcessText( IntPtr hContext ,[MarshalAs(UnmanagedType.LPWStr)] string szText ,[MarshalAs(UnmanagedType.LPWStr)] string szTextID ,FX_TEXT_FORMAT eFormat ,out IntPtr phResult);
//FX_ERROR __stdcall FXDestroyResult(FX_HANDLE hResult) [DllImport(DllPath ,CallingConvention = CallingConvention.StdCall ,CharSet = CharSet.Unicode ,SetLastError = true)] public extern static FX_ERROR FXDestroyResult(IntPtr hResult);
// ... } |
|
|
Михаил Машкович |
30.03.09, 11:46 |
|
re: re: re: Как использовать RCOFXRu.dll со сборкой .net? |
|
[DllImport("kernel32.dll",SetLastError = true,CharSet = CharSet.Auto)] internal static extern IntPtr LoadLibrary(string lpFileName);
[DllImport("kernel32.dll",SetLastError = true,CharSet = CharSet.Auto)] internal static extern bool FreeLibrary(IntPtr hModule);
class Analyzer : IDisposable { private IntPtr ptrContext = IntPtr.Zero; private IntPtr ptrResource = IntPtr.Zero; IntPtr lPtr = IntPtr.Zero; string dllName = "RCOFXRu.dll"; string resourcesPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),"Resources"); public Analyzer() { lPtr = LoadLibrary(Path.Combine(resourcesPath,dllName)); if (lPtr == null || lPtr == IntPtr.Zero) throw new Exception("Библиотека не может быть загружена!"); //создаем рабочий контекст FX_FILE_RESOURCE_MANAGER mgr = new FX_FILE_RESOURCE_MANAGER(); mgr.OpenResource = new OpenResourceDelegate(Analyzer.OpenResource); mgr.CloseResource = new CloseResourceDelegate(Analyzer.CloseResource); mgr.ReadResource = new ReadResourceDelegate(Analyzer.ReadResource); ptrResource = Marshal.AllocHGlobal(Marshal.SizeOf(mgr)); Marshal.StructureToPtr(mgr,ptrResource,true); string configuration = string.Empty; using (StreamReader sr = new StreamReader("config.xml", Encoding.Default)) configuration = sr.ReadToEnd(); try { FX_ERROR result = FXAPI.FXCreateContext(configuration ,ref ptrResource ,out ptrContext); if (result != FX_ERROR.SUCCESS) throw new Exception(result.ToString()); } finally { if (ptrResource != null && ptrResource != IntPtr.Zero) { Marshal.DestroyStructure(ptrResource ,typeof(FX_FILE_RESOURCE_MANAGER)); } } }
#region IDisposable Members
//Деструктор, выполняющий очистку ресурсов если она не была еще проведена ~Analyzer() { //Вызываем Dispose с параметром false, для очистки только //unmanaged-ресурсов. Dispose(false); }
public void Dispose() { Dispose(true); //Запретим вызов метода Finalize для данного класса, так как мы //уже сами все очистили. GC.SuppressFinalize(this); }
private bool _disposed = false; protected virtual void Dispose(bool disposing) { //Проверим что метод вызван впервые и выполним очистку if (!this._disposed) { if (disposing) { //очистка managed-ресурсов if (ptrContext != null && ptrContext != IntPtr.Zero) { FXAPI.FXDestroyContext(ptrContext); } } //очистка unmanaged-ресурсов if (ptrResource != null && ptrResource != IntPtr.Zero) { Marshal.FreeHGlobal(ptrResource); } if (lPtr != null && lPtr != IntPtr.Zero) { FreeLibrary(lPtr); } GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect(); } _disposed = true; }
#endregion
internal Document ProcessText(string szText,Uri szDocName) { UInt32 offset = 0; UInt32 length = 0; UInt32 textLength = 0; UInt32 uintValueSize = sizeof(UInt32); StringBuilder text; IntPtr hResult = IntPtr.Zero; FX_ERROR result = FXAPI.FXProcessText(ptrContext ,szText ,szDocName.OriginalString ,FX_TEXT_FORMAT.AUTO , out hResult); // ... } }
Немного сумбурно, но разобраться, думаю, можно, если нет - пишите, попробуем выделить время и сделать небольшое тестовое приложение. |
|
|
Catnip |
07.05.09, 12:19 |
|
Ошибка. |
|
При попытке вызвать импортированную так же, как показано в примере, функцию FXCreateContext возникает исключение AccessViolationException. Что это и как с этим бороться?
В случае, если представленной информации недостаточно - можем выслать исходник на C# и инструкции по повторению ошибки. |
|
|
Михаил Машкович |
07.05.09, 13:00 |
|
re: Ошибка. |
|
Присылайте, также напишите о машине - версия винды, включены ли UAC и DEP. |
|
|
Голенков Владимир |
07.05.09, 13:54 |
|
альтернативный вариант |
|
альтернативным вариантом использования может быть создание ActiveX-обертки с заданным интерфейсом и функциональностью, скажем, с помощью VC++ и ATL.
Результатом ее работы может быть xml с соответствующим разбором на стороне .net
Дополнительным плюсом является возможность "прозрачного" оборачивания в com+ пакет, что дает защиту от возможного краха dll |
|
|
Catnip |
08.05.09, 11:06 |
|
Исходник |
|
Здравствуйте. ОС - Windows XP UAC - отсутствует DEP - включен для основных программ и служб Windows
Исходник:
http://rapidshare.com/files/230496932/RCOConsole.zip.html
Ошибка - в файле Pinvoke.cs, 253 строка. |
|
|
Михаил Машкович |
08.05.09, 15:30 |
|
re: Исходник |
|
Да, падает, при этом в системный лог "Application" записывается ошибка: "//HASP HL Protection System //Error 1009: Cannot open HASP HL drivers" У вас похоже защищенная dll-ка RCOFxRu.dll. |
|
|
Catnip |
12.05.09, 13:07 |
|
re: re: Исходник |
|
Уважаемый Михаил, библиотека у нас и правда закрытая, но у нас есть HASP-ключ, он вставлен и опознаётся, подобных сообщений об ошибках в системном логе нет (но если приложение запустить без ключа - они появляются). Так что наша проблема, видимо, не в HASPе.
Я надеюсь, что несмотря на невозможность передать вам ключ, вы, как разработчики, можете использовать свой ключ либо незакрытую версию библиотеки для запуска приложения.
В надежде на это, прилагаю версию библиотеки, которой мы пользуемся: RCO FX Russian 1.5 Professional (RCOFXRu.dll 1.5.0.1)
Надеюсь на ваш ответ. |
|
|
Михаил Машкович |
12.05.09, 13:15 |
|
re: re: re: Исходник |
|
Хотелось для начала отсеить наиболее очевидные проблемы. Хорошо, сегодня попробую отладиться на этой версии и выдать рекомендации или работающий вариант кода. |
|
|
Михаил Машкович |
12.05.09, 14:38 |
|
re: re: re: re: Исходник |
|
Пока ищем подходящую версию, попробуйте вот этот код http://demo.rco.ru/download/rcoConsole.zip NB: Сборку и библиотеки я удалил, чтобы сократить объем архива, вы их залейте, пожалуйста, в папку "RCO.FX.Binaries", в корне проекта (папки dic, ld, objects и саму dll-ку). |
|
|
Catnip |
13.08.09, 10:01 |
|
AccessViolationException |
|
И вновь здравствуйте. У нас вновь возникла проблема с RCO. А именно, при вызове FXGetFirst с параметром FX_INFO_ENTITY_FOR_FRAME_SLOT генерируется исключение AccessViolationException. Хотелось бы комментарии по этому поводу.
Исходный код, иллюстрирующий проблему, можно взять по ссылке: http://dl.getdropbox.com/u/814679/RCOConsole.zip
|
|
|
Михаил Машкович |
13.08.09, 10:36 |
|
re: AccessViolationException |
|
Добрый день!
Посмотрим, постараемся разобраться. Пока можете посмотреть на нашу обертку на C#, которая эмулирует тестовое приложение test.exe, описанное в документации. http://nisus-2.hosting.parking.ru/FX.NET.zip |
|
|
Catnip |
13.08.09, 13:23 |
|
Благодарность. |
|
Большое спасибо, проблема разрешена. Ещё раз благодарю Вас за помощь. |
|
|
Catnip |
12.11.09, 13:19 |
|
Нулевой указатель при вызове LoadLibrary. |
|
Здравствуйте.
Вновь возникла проблема. При вызове LoadLibrary, импортированной из kernel32.dll из-под Windows Server 2003 64bit возвращается нулевой указатель. Подобное поведение проявляет и ваш пример (FX.NET). В чём может быть проблема и как нам подойти к её решению? |
|
|
Машкович Михаил |
12.11.09, 20:50 |
|
re: Нулевой указатель при вызове LoadLibrary. |
|
Добрый вечер!
Поскольку у вас FX 32-х битный, то необходимо компилировать управляемую обертку под платформу x86, а не под AnyCPU. |
|
|
Liya |
26.12.11, 15:37 |
|
re: re: AccessViolationException |
|
Здравствуйте! Мы пробуем использовать вашу библиотеку. Увидели, что у вас уже есть обертка на C# и очень хотим с ней поработать. У вас еще остались ее исходные коды? Или ее можно скачать где-то на вашем сайте?
>Добрый день! > >Посмотрим, постараемся разобраться. Пока можете посмотреть на нашу обертку на C#, которая эмулирует тестовое приложение test.exe, описанное в документации. http://nisus-2.hosting.parking.ru/FX.NET.zip
|
|
|
Михаил Машкович |
26.12.11, 15:43 |
|
re: re: re: AccessViolationException |
|
Добрый день!
Начните с этой обертки. Сейчас библиотека ушла вперед, но для старта вам должно хватить. Будут проблемы - обращайтесь: http://ftp.rco.ru/download/FX.NET.zip |
|
|
|
|
|
| |