![]() |
#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 |
|
![]() |
#2 |
Участник
|
А зачем нужно переделывать C# код на Х++ для 3.0? По-моему, проще будет сделать обертку на C# и дергать ее из 3.0 через COM. Я лично делал примерно так:
|
|
|
За это сообщение автора поблагодарили: AlexSt (1). |
![]() |
#3 |
Участник
|
Просто есть dll компонента для подключения Wi-Fi ТСД в ней организованы Native функции, к компоненте есть пример на C#, по этому примеру идет подключение к компоненте dll и обращения к определенным функциям компоненты. Но в примере чтобы подключить нужно получить дескриптор handle функции для подключения и затем применять его везде (передача + приём данных в AX)
__________________
Axapta 3.0 SP6 Build 1951 |
|
![]() |
#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 |
|
![]() |
#5 |
Участник
|
как в данном случае можно получить дескриптор в функции Enable dll библиотеки CipherLabTCP.dll на языке X++?
__________________
Axapta 3.0 SP6 Build 1951 |
|
![]() |
#6 |
Участник
|
Как в аксапте можно сделать такую вещь:
IntPtr m_server, где IntPtr определяемый платформой тип, который используется для представления указателя или дескриптора, как можно представить в X ++ IntPtr?
__________________
Axapta 3.0 SP6 Build 1951 |
|
![]() |
#7 |
Участник
|
X++: int i = 5; System.IntPtr IntPtr = new System.IntPtr(i); |
|
![]() |
#8 |
Участник
|
Делаю так
int i = 5; System.IntPtr IntPtr = new System.IntPtr(i); Пишет что Таблица не содержит это поле и курсор мигает перед System. В чем может быть проблема?
__________________
Axapta 3.0 SP6 Build 1951 |
|
![]() |
#9 |
Участник
|
|
|
![]() |
#10 |
Участник
|
что то никак не могу найти References есть ли в Axapta 3.0 References?
__________________
Axapta 3.0 SP6 Build 1951 |
|
![]() |
#11 |
Участник
|
Правда, нет. Прошу прощения, тогда код выше применим только для 2009 и выше. Насчёт 4.0 не знаю, может там уже поддерживается .NET.
Последний раз редактировалось Cardagant; 28.02.2014 в 15:53. |
|
![]() |
#12 |
Участник
|
Посмотрите, как реализован вызов, к примеру, WinAPI::getComputerName() - там по ссылке передается DWORD, куда вызываемая функция записывает длину строки с названием компьютера. Обратите внимание, что тип аргументов функции указываются как ExtTypes::Pointer.
|
|
![]() |
#13 |
Участник
|
А ещё где можно посмотреть как в Аксапте 3.0 получить дескриптор файла из функции библиотеки dll? А так же как можно представить IntPtr в Аксапте 3.0
__________________
Axapta 3.0 SP6 Build 1951 |
|
![]() |
#14 |
Участник
|
Я хотел бы ещё поинтересоваться, как можно построить в Axapta 3.0 указатель на дескриптор? Дескриптор имеет значение Void
__________________
Axapta 3.0 SP6 Build 1951 |
|
![]() |
#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 |
|
![]() |
#16 |
Участник
|
с void* всё верно. Описание функции нашёл
Название: int cipherlabtcpCreate(void** ptrtohandle) Входные параметры: - ptrtohandle (OUT) - указатель на дескриптор сервера-компоненты (дескриптор имеет тип void*), который используется в последующих вызовах, может быть равен NULL. Значение дескриптора должно быть инициализировано NULL. Выходные параметры: код ошибки Описание: Инициализация компоненты-объекта сервера .Создается объект-сервера. Если ptrtohandle равен NULL, подразумевается использование одной "глобальной" компоненты-сервера.
__________________
Axapta 3.0 SP6 Build 1951 |
|
![]() |
#17 |
Участник
|
gl00mie
Как я понимаю если указатель на дескриптор, то нужно пользоваться ExtTypes::Pointer, а если входной параметр Int, то тут нужно задавать как ExtTypes: ![]()
__________________
Axapta 3.0 SP6 Build 1951 |
|
![]() |
#18 |
Участник
|
Скажем так, если в качестве входного параметра API-функции нужно передать ссылку на область памяти, куда функция будет что-то писать, либо указатель на структуру данных, которую нужно сформировать из X++ с учетом того, что там нет работы с указателями, то надо указывать тип параметра ExtTypes::Pointer. В этом случае DLLFunction поймет, что соответствующий параметр, переданный из X++, надо передать дальше по ссылке. Если же параметр API-функции - просто значение некоего указателя (const void*), которое вызывающий код X++ получает извне, то для DLLFunction тип такого параметра можно указать как ExtTypes::DWord и передавать соотв. значение указателя как целое число.
|
|
|
За это сообщение автора поблагодарили: Logger (5), ShkipeRR (1). |
![]() |
#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 |
|
![]() |
#20 |
Участник
|
Появилась возможность спрограммировать отдельное приложение-сервис на основе компоненты CipherLabTCP.dll. которая будет осуществлять автоматическое подключение к ТСД и передачу данных с ТСД через программу сервис аксапте,
подскажите по такому вопросу, как будет лучше принять данные с программы-сервис аксапте 3.0? Ситуация такова будет: ТСД отсылает данные в виде штрих-кода (к примеру: 4301031235466) программе сервис, получает данные и пересылает аксапте, и вопрос будет вот в чем стоять как будет лучше принять данные с программы сервис и отправить обратное сообщение программе сервис, чтобы в дальнейшем сервис программа отослала это сообщение на дисплей ТСД (двунаправленная связь)? Т.е. ТСД - программа сервис - Аксапта 3.0
__________________
Axapta 3.0 SP6 Build 1951 |
|