|  25.02.2014, 14:47 | #1 | 
| Участник | Дескриптор или как получить Handle функции из dll компоненты 
			
			Имеется пример написанный на языке C#, так же есть ИС Axapta 3.0. В примере сначала по коду создают объект функции и получают дескриптор handle Пример из C# public partial class FormMain : Form { IntPtr m_server; int m_port; BindingList<TcpTerminal> m_terminals; int m_alertcount=0; const int WM_APP=0x8000; const int MAXSNSIZE=256; const int MAXFIELDSIZE=256; public FormMain() { InitializeComponent(); m_server=IntPtr.Zero; m_port=1024; m_terminals=new BindingList<TcpTerminal>(); listBoxTerminals.DataSource=m_terminals; listBoxTerminals.DisplayMember="SerialNumber"; comboBoxMessageType.SelectedIndex=0; buttonMessageSend.Enabled=false; buttonMessageSendAll.Enabled=false; buttonSendAnswer.Enabled=false; UpdateBottomControls(); } получение Handle: private void buttonStartStop_Click(object sender,EventArgs e) { int res; if(m_server==IntPtr.Zero) { res=cipherlabtcpCreate(ref m_server); } } в переменной m_server формируется ссылка (дескриптор), который дальше участвует в программном коде Проблема заключается в том, как перевести C# на программный код X++ и получить ссылку Handle? Первоначально m_server обозначают как IntPtr, но в X++ (Axapta) такого нет, так как нет в x++ встал вопрос как инициализировать m_server? в примере на C# инициализируют как m_server=IntPtr.Zero (дескриптор, инициализированный с нулевым значением.) Подскажите пожалуйста как можно получить дескриптор в x++ Axapta согласно куска примера на C#? 
				__________________ Axapta 3.0 SP6 Build 1951 | 
|  | 
|  25.02.2014, 16:04 | #2 | 
| Участник | 
			
			А зачем нужно переделывать C# код на Х++ для 3.0? По-моему, проще будет сделать обертку на C# и дергать ее из 3.0 через COM. Я лично делал примерно так: 
 | 
|  | |
| За это сообщение автора поблагодарили: AlexSt (1). | |
|  25.02.2014, 16:29 | #3 | 
| Участник | 
			
			Просто есть dll компонента для подключения Wi-Fi ТСД в ней организованы Native функции, к компоненте есть пример на C#, по этому примеру идет подключение к компоненте dll и обращения к определенным функциям компоненты. Но в примере чтобы подключить нужно получить дескриптор handle функции для подключения и затем применять его везде (передача + приём данных в AX)
		 
				__________________ Axapta 3.0 SP6 Build 1951 | 
|  | 
|  26.02.2014, 14:18 | #4 | 
| Участник | 
			
			Вот что в Аксапте получилось X++: static void Job77(Args _args) { Int // Номер порта Int // Результат int // Метод записи int // Отладка Int // Номер ошибки void void void void int Binary Counter // Номер БД в ТСД всего их 3 Counter // Номера форм в ТСД всего их 8мь M583_ImportedData Int Binary Binary Binary Binary Binary Binary Binary Binary DLL // Драйвер терминала (CipherLabTCP.dll) DLLFunction // Подключить (cipherlabtcpStart) DLLFunction // Отключить (cipherlabtcpStop) DLLFunction // Инициализация компоненты объекта сервера (cipherlabtcpCreate) DLLFunction // Получение строки события в обработчике события (cipherlabtcpGetEvent) DLLFunction // Устанавливает callback функцию для события от ТСД (cipherlabtcpSetEventCallback) DLLFunction // Задание оконного сообщения для события (cipherlabtcpSetEventMassega) DLLFunction // Удаленее ранее созданного объекта сервера (cipherlabtcpDestroty) DLLFunction // Пинг (cipherlabtcpPing) DLLFunction // Получить данные (cipherlabtcpGetData) DLLFunction // Получить серийный номер ТСД (cipherlabtcpGetSerialNumber) DLLFunction // Послать ответ на ТСД (cipherlabtcpAnswer) DLLFunction // Получить параметры с ТСД (cipherlabtcpGetProperties) DLLFunction // Назначить параметры ТСД (cipherlabtcpSetPropierties) DLLFunction // Послать сообщение на ТСД без вибро сигнала (cipherlabtcpSendMessage) DLLFunction // Послать предупреждение на ТСД с вибро сигналом и миганием свет диода (cipherlabtcpSendWarning) CipherLabTCP = new DLL("CipherLabTCP") // Драйвер терминала GetProperties = new DLLFunction(CipherLabTCP, 'cipherlabtcpGetProperties') // Получение параметров SetProperties = new DLLFunction(CipherLabTCP, 'cipherlabtcpSetProperties') // Назначение параметров Enable = new DLLFunction(CipherLabTCP, 'cipherlabtcpCreate') // Инициализация компоненты объекта сервера Attach = new DLLFunction(CipherLabTCP, 'cipherlabtcpStart') // Запуск сервера Deattach = new DLLFunction(CipherLabTCP, 'cipherlabtcpStop') // Остановка сервера Destroy = new DLLFunction(CipherLabTCP, 'cipherlabtcpDestroy') // Освобождение ресурсов SetEventCallback = new DLLFunction(CipherLabTCP, 'cipherlabtcpSetEventCallback') // Устанавливает callback функцию для события от ТСД GetEvent = new DLLFunction(CipherLabTCP, 'cipherlabtcpGetEvent') // Получение строки события GetDataSN = new DLLFunction(CipherLabTCP, 'cipherlabtcpGetSerialNumber') // Получить серийный номер ТСД Port = SaveMethod = Debug = Enable.returns(ExtTypes::void) Enable.arg(ExtTypes::void) ErrorNumber = Enable.call(ptrtohandle) if (ErrorNumber == 0) { SetEventCallback.returns(ExtTypes::void) SetEventCallback.arg(ExtTypes::void, ExtTypes::void, ExtTypes::void) ErrorNumber = SetEventCallback.call(ptrtohandle, callbackfunc, param1) GetProperties.returns(ExtTypes::void) GetProperties.arg(ExtTypes::void, ExtTypes::void, ExtTypes::void, ExtTypes::void) ErrorNumber = GetProperties.call(ptrtohandle, Port, SaveMethod, Debug) SetProperties.returns(ExtTypes::void) SetProperties.arg(ExtTypes::void, ExtTypes::void, ExtTypes::void, ExtTypes::void) ErrorNumber = SetProperties.call(ptrtohandle, Port, SaveMethod, Debug) Attach.returns(ExtTypes::void) Attach.arg(ExtTypes::void) ErrorNumber = Attach.call(ptrtohandle) if (ErrorNumber != 0) { Deattach.returns(ExtTypes::DWord) Deattach.arg(ExtTypes::void) Deattach.call(ptrtohandle) Destroy.returns(ExtTypes::DWord) Destroy.arg(ExtTypes::void) Destroy.call(ptrtohandle) warning ("Не удалось подключиться. Переподключите ТСД к WiFi") } } else { Deattach.returns(ExtTypes::DWord) Deattach.arg(ExtTypes::void) Deattach.call(ptrtohandle) Destroy.returns(ExtTypes::void) Destroy.arg(ExtTypes::void) Destroy.call(ptrtohandle) warning ("Не удалось подключиться. Переподключите ТСД к WiFi") } } 
				__________________ Axapta 3.0 SP6 Build 1951 | 
|  | 
|  27.02.2014, 12:41 | #5 | 
| Участник | 
			
			как в данном случае можно получить дескриптор в функции Enable dll библиотеки CipherLabTCP.dll на языке X++?
		 
				__________________ Axapta 3.0 SP6 Build 1951 | 
|  | 
|  28.02.2014, 15:18 | #6 | 
| Участник | 
			
			Как в аксапте можно сделать такую вещь: IntPtr m_server, где IntPtr определяемый платформой тип, который используется для представления указателя или дескриптора, как можно представить в X ++ IntPtr? 
				__________________ Axapta 3.0 SP6 Build 1951 | 
|  | 
|  28.02.2014, 15:24 | #7 | 
| Участник | X++: int i = 5; System.IntPtr IntPtr = new System.IntPtr(i); | 
|  | 
|  28.02.2014, 15:27 | #8 | 
| Участник | 
			
			Делаю так  int i = 5; System.IntPtr IntPtr = new System.IntPtr(i); Пишет что Таблица не содержит это поле и курсор мигает перед System. В чем может быть проблема? 
				__________________ Axapta 3.0 SP6 Build 1951 | 
|  | 
|  28.02.2014, 15:32 | #9 | 
| Участник | |
|  | 
|  28.02.2014, 15:38 | #10 | 
| Участник | 
			
			что то никак не могу найти References есть ли в Axapta 3.0 References?
		 
				__________________ Axapta 3.0 SP6 Build 1951 | 
|  | 
|  28.02.2014, 15:43 | #11 | 
| Участник | 
			
			Правда, нет. Прошу прощения, тогда код выше применим только для 2009 и выше. Насчёт 4.0 не знаю, может там уже поддерживается .NET.
		 Последний раз редактировалось Cardagant; 28.02.2014 в 15:53. | 
|  | 
|  28.02.2014, 16:51 | #12 | 
| Участник | 
			
			Посмотрите, как реализован вызов, к примеру, WinAPI::getComputerName() - там по ссылке передается DWORD, куда вызываемая функция записывает длину строки с названием компьютера. Обратите внимание, что тип аргументов функции указываются как ExtTypes::Pointer.
		 | 
|  | 
|  03.03.2014, 11:07 | #13 | 
| Участник | 
			
			А ещё где можно посмотреть как в Аксапте 3.0 получить дескриптор файла из функции библиотеки dll? А так же как можно представить IntPtr в Аксапте 3.0
		 
				__________________ Axapta 3.0 SP6 Build 1951 | 
|  | 
|  04.03.2014, 10:46 | #14 | 
| Участник | 
			
			Я хотел бы ещё поинтересоваться, как можно построить в Axapta 3.0 указатель на дескриптор? Дескриптор имеет значение Void
		 
				__________________ Axapta 3.0 SP6 Build 1951 | 
|  | 
|  04.03.2014, 11:53 | #15 | 
| Участник | 
			
			В 3.0 нет никаких IntPtr; дескриптор, вероятнее всего, имеет тип не void, а void*. В данном случае при вызове функции cipherlabtcpCreate() нужно передать указатель на область памяти размером в 4 байта, куда функция запишет дескриптор - некое значение, имеющее смысл для других API-функций CipherLabTCP. Затем полученный дескриптор надо будет, вероятнее всего, по значению (а не по ссылке) передавать в прочие API-функции CipherLabTCP. Пример того, как правильно через DLLFunction описать API-функцию, принимающую указатель в качестве параметра, и как потом получить записанное функцией значение, можно найти в WinAPI::getComputerName(). Что именно не получается с этим примером? PS. Описывать через DLLFunction, будто бы функция cipherlabtcpCreate() вообще не принимает на вход параметров (ExtTypes::void), в корне неверно. Тип void* означает "нетипизированный указатель" и с ExtTypes::void он не имеет ничего общего; указатель в терминах DLLFunction - это ExtTypes::Pointer. Последний раз редактировалось gl00mie; 04.03.2014 в 11:59. Причина: PS | 
|  | 
|  04.03.2014, 12:26 | #16 | 
| Участник | 
			
			с void* всё верно. Описание функции нашёл Название: int cipherlabtcpCreate(void** ptrtohandle) Входные параметры: - ptrtohandle (OUT) - указатель на дескриптор сервера-компоненты (дескриптор имеет тип void*), который используется в последующих вызовах, может быть равен NULL. Значение дескриптора должно быть инициализировано NULL. Выходные параметры: код ошибки Описание: Инициализация компоненты-объекта сервера .Создается объект-сервера. Если ptrtohandle равен NULL, подразумевается использование одной "глобальной" компоненты-сервера. 
				__________________ Axapta 3.0 SP6 Build 1951 | 
|  | 
|  04.03.2014, 14:46 | #17 | 
| Участник | 
			
			gl00mie Как я понимаю если указатель на дескриптор, то нужно пользоваться ExtTypes::Pointer, а если входной параметр Int, то тут нужно задавать как ExtTypes:  _Word (Дворд)? 
				__________________ Axapta 3.0 SP6 Build 1951 | 
|  | 
|  04.03.2014, 16:32 | #18 | 
| Участник | 
			
			Скажем так, если в качестве входного параметра API-функции нужно передать ссылку на область памяти, куда функция будет что-то писать, либо указатель на структуру данных, которую нужно сформировать из X++ с учетом того, что там нет работы с указателями, то надо указывать тип параметра ExtTypes::Pointer. В этом случае DLLFunction поймет, что соответствующий параметр, переданный из X++, надо передать дальше по ссылке. Если же параметр API-функции - просто значение некоего указателя (const void*), которое вызывающий код X++ получает извне, то для DLLFunction тип такого параметра можно указать как ExtTypes::DWord и передавать соотв. значение указателя как целое число.
		 | 
|  | |
| За это сообщение автора поблагодарили: Logger (5), ShkipeRR (1). | |
|  05.03.2014, 15:13 | #19 | 
| Участник | 
			
			у меня в примере на C# присутствует такая вещь. Кусок кода из примера: private void buttonStartStop_Click(object sender,EventArgs e) { int res; if(m_server==IntPtr.Zero) { res=cipherlabtcpCreate(ref m_server); Alert("cipherlabtcpCreate",res); res=cipherlabtcpSetEventMessage(m_server,this.Handle,WM_APP,IntPtr.Zero); Alert("cipherlabtcpSetEventMessage",res); res=cipherlabtcpSetProperties(m_server,m_port,checkBoxSaveMethod.Checked?1:0,checkBoxDebug.Checked?1:0); Alert("cipherlabtcpSetProperties",res); res=cipherlabtcpStart(m_server); Alert("cipherlabtcpStart",res); MessageBoxResult(res); } void Alert(string msg) { listBoxLog.Items.Add(System.String.Format("{0}. {1}",++m_alertcount,msg)); } void Alert(string msg,int code) { Alert(System.String.Format("{0} (code: {1})",msg,code)); } как в аксапте можно представить Alert, к примеру Alert("cipherlabtcpCreate",res) и есть ли такая возможность в аксапте как в C# Alert? 
				__________________ Axapta 3.0 SP6 Build 1951 | 
|  | 
|  12.03.2014, 09:33 | #20 | 
| Участник | 
			
			Появилась возможность спрограммировать отдельное приложение-сервис на основе компоненты CipherLabTCP.dll. которая будет осуществлять автоматическое подключение к ТСД и передачу данных с ТСД через программу сервис аксапте, подскажите по такому вопросу, как будет лучше принять данные с программы-сервис аксапте 3.0? Ситуация такова будет: ТСД отсылает данные в виде штрих-кода (к примеру: 4301031235466) программе сервис, получает данные и пересылает аксапте, и вопрос будет вот в чем стоять как будет лучше принять данные с программы сервис и отправить обратное сообщение программе сервис, чтобы в дальнейшем сервис программа отослала это сообщение на дисплей ТСД (двунаправленная связь)? Т.е. ТСД - программа сервис - Аксапта 3.0 
				__________________ Axapta 3.0 SP6 Build 1951 | 
|  |