AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 25.02.2014, 14:47   #1  
ShkipeRR is offline
ShkipeRR
Участник
 
41 / 7 (1) +
Регистрация: 08.05.2013
Адрес: Владимир
Дескриптор или как получить 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  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5803 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
А зачем нужно переделывать C# код на Х++ для 3.0? По-моему, проще будет сделать обертку на C# и дергать ее из 3.0 через COM. Я лично делал примерно так:
  • в VS создавал проект по шаблону Class Library под .NET Framework 4.0
  • в C# создавал public-класс с атрибутом ClassInterface(ClassInterfaceType.AutoDispatch) - атрибут объявлен в пространстве имен System.Runtime.InteropServices;
  • собирал сборку и клал ее рядом с исполняемым файлом ядра Аксапты 3.0 (в моем случае это был АОС)
  • регистрировал сборку в качестве COM-компоненты с помощью regasm (обычно располагается в каталоге %SystemRoot%\Microsoft.NET\Framework\v4.0.30319):
    Код:
    RegAsm название_сборки.dll
    RegAsm название_сборки.dll /tlb
    второе вроде как опционально, но мало ли
И все, дальше можно в Х++ создавать через COM экземпляр класса и дергать его методы; разумеется, при этом налагаются определенные ограничения на типы параметров и возвращаемых значений методов. Если для сборки нужны какие-то настройки, то их надо будет прописать в config-файл (например, ax32serv.exe.config) и положить рядом с файлом ядра Аксапты.
За это сообщение автора поблагодарили: AlexSt (1).
Старый 25.02.2014, 16:29   #3  
ShkipeRR is offline
ShkipeRR
Участник
 
41 / 7 (1) +
Регистрация: 08.05.2013
Адрес: Владимир
Просто есть dll компонента для подключения Wi-Fi ТСД в ней организованы Native функции, к компоненте есть пример на C#, по этому примеру идет подключение к компоненте dll и обращения к определенным функциям компоненты. Но в примере чтобы подключить нужно получить дескриптор handle функции для подключения и затем применять его везде (передача + приём данных в AX)
__________________
Axapta 3.0 SP6 Build 1951
Старый 26.02.2014, 14:18   #4  
ShkipeRR is offline
ShkipeRR
Участник
 
41 / 7 (1) +
Регистрация: 08.05.2013
Адрес: Владимир
Вот что в Аксапте получилось
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")
}
}
Из этого кода не получается получить дескриптор ptrtohandle и код ошибки всегда 0, так как дескриптор функции Enable не получается получить не идёт Wi-Fi подключение к компоненте dll, подскажите пожалуйста как в этом коде можно получить дескриптор функии Enable чтобы в дальнейшем этот дескриптор использовать?
__________________
Axapta 3.0 SP6 Build 1951
Старый 27.02.2014, 12:41   #5  
ShkipeRR is offline
ShkipeRR
Участник
 
41 / 7 (1) +
Регистрация: 08.05.2013
Адрес: Владимир
как в данном случае можно получить дескриптор в функции Enable dll библиотеки CipherLabTCP.dll на языке X++?
__________________
Axapta 3.0 SP6 Build 1951
Старый 28.02.2014, 15:18   #6  
ShkipeRR is offline
ShkipeRR
Участник
 
41 / 7 (1) +
Регистрация: 08.05.2013
Адрес: Владимир
Как в аксапте можно сделать такую вещь:
IntPtr m_server, где IntPtr определяемый платформой тип, который используется для представления указателя или дескриптора, как можно представить в X ++ IntPtr?
__________________
Axapta 3.0 SP6 Build 1951
Старый 28.02.2014, 15:24   #7  
Cardagant is offline
Cardagant
Участник
 
317 / 54 (2) ++++
Регистрация: 11.10.2011
X++:
int             i = 5;
System.IntPtr   IntPtr = new System.IntPtr(i);
Старый 28.02.2014, 15:27   #8  
ShkipeRR is offline
ShkipeRR
Участник
 
41 / 7 (1) +
Регистрация: 08.05.2013
Адрес: Владимир
Делаю так
int i = 5;
System.IntPtr IntPtr = new System.IntPtr(i);

Пишет что Таблица не содержит это поле и курсор мигает перед System.
В чем может быть проблема?
__________________
Axapta 3.0 SP6 Build 1951
Старый 28.02.2014, 16:51   #9  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5803 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Посмотрите, как реализован вызов, к примеру, WinAPI::getComputerName() - там по ссылке передается DWORD, куда вызываемая функция записывает длину строки с названием компьютера. Обратите внимание, что тип аргументов функции указываются как ExtTypes::Pointer.
Старый 03.03.2014, 11:07   #10  
ShkipeRR is offline
ShkipeRR
Участник
 
41 / 7 (1) +
Регистрация: 08.05.2013
Адрес: Владимир
А ещё где можно посмотреть как в Аксапте 3.0 получить дескриптор файла из функции библиотеки dll? А так же как можно представить IntPtr в Аксапте 3.0
__________________
Axapta 3.0 SP6 Build 1951
Старый 04.03.2014, 10:46   #11  
ShkipeRR is offline
ShkipeRR
Участник
 
41 / 7 (1) +
Регистрация: 08.05.2013
Адрес: Владимир
Я хотел бы ещё поинтересоваться, как можно построить в Axapta 3.0 указатель на дескриптор? Дескриптор имеет значение Void
__________________
Axapta 3.0 SP6 Build 1951
Старый 12.03.2014, 10:38   #12  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5803 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Цитата:
Сообщение от ShkipeRR Посмотреть сообщение
Имеется пример написанный на языке C#, так же есть ИС Axapta 3.0. Подскажите пожалуйста как можно получить дескриптор в x++ Axapta согласно куска примера на C#?
Цитата:
Сообщение от ShkipeRR Посмотреть сообщение
Вот что в Аксапте получилось [...] подскажите пожалуйста как в этом коде можно получить дескриптор функии Enable чтобы в дальнейшем этот дескриптор использовать?
Цитата:
Сообщение от gl00mie Посмотреть сообщение
Посмотрите, как реализован вызов, к примеру, WinAPI::getComputerName()
Цитата:
Сообщение от ShkipeRR Посмотреть сообщение
у меня в примере на C# присутствует такая вещь [...] как в аксапте можно представить Alert, к примеру Alert("cipherlabtcpCreate",res) и есть ли такая возможность в аксапте как в C# Alert?
Цитата:
Сообщение от ShkipeRR Посмотреть сообщение
Появилась возможность спрограммировать отдельное приложение-сервис на основе компоненты CipherLabTCP.dll. как будет лучше принять данные с программы сервис и отправить обратное сообщение программе сервис, чтобы в дальнейшем сервис программа отослала это сообщение на дисплей ТСД (двунаправленная связь)?
У вас реализация связи с ТСД через CipherLabTCP.dll - это реальная задача или учебная? Если учебная, то возьмите книжки - тот же MorphX IT, который есть в открытом доступе, почитайте, поизучайте tutorial-формы, таблицы и классы... А если реальная, то зачем эти пляски вокруг да около с Alert'ами и программами-сервисами, просто посмотрите пример реализации вызова в классе WinAPI и сделайте по аналогии.

PS. Хотя уже слабо верится, что на решение реальной задачи кто-то может отвести столько времени...

Последний раз редактировалось gl00mie; 12.03.2014 в 10:40. Причина: PS
Старый 12.03.2014, 12:32   #13  
ShkipeRR is offline
ShkipeRR
Участник
 
41 / 7 (1) +
Регистрация: 08.05.2013
Адрес: Владимир
Это реальная задача, только вот никак не получается подключится к компоненте, из примера смотришь вроде легко, для аксапты сложновато. в ступор сразу ввел указатель на дескриптор, а точнее создаем объект функцией cipherlabtcpCreate и получаем дескриптор сервера-
компоненты handle.
никак не получается этот дескриптор Handle получить в аксапте 3.0. в примере этот дескриптор при обращении к функции cipherlabtcpCreate получается сразу 8 знаков в аксапте он получается 0. в результате автоматическое подключение к ТСД не происходит.
__________________
Axapta 3.0 SP6 Build 1951
Старый 18.03.2014, 09:15   #14  
ShkipeRR is offline
ShkipeRR
Участник
 
41 / 7 (1) +
Регистрация: 08.05.2013
Адрес: Владимир
Ничего не получается с WinAPI будет программироваться отдельная программа для соединения ТСД с Аксаптой, будущая программа-сервис будет выполнять следующее:
1. Автоматически запускаться в виде сервиса, если программа-сервис дала сбой, то автоматически перезапускаться (при запуске происходит подключение к ТСД, если ТСД проявил активность);
2. После того как программа сервис была запущена на сервере, программа – сервис должна ожидать данные от терминалов сбора данных;
3. Как только какой-то терминал сбора данных проявит свою активность в функции-обработчике сначала нужно узнать тип события. Всего может быть 5 типов событий от ТСД: MAKE, CLOSE, QUERY, INSERT, UPDATE;
4. Выяснить серийный номер ТСД, который вызвал событие;
5. Получить данные из ТСД вместе с серийным номером от ТСД;
6. Отправить полученные данные из ТСД в ИС Axapta;
7. Ожидать ответа от ИС Axapta по полученным данным из ТСД;
- Если в течении 5 секунд ответа нет, то освободить ресурсы для приема следующих данные от ТСД;
- Если в течении 5 секунд ответ в программу сервер пришёл, то:
a) принять ответ от Axapta в программу-сервис;
b) отправить полученный ответ на дисплей ТСД, который вызвал событие (по серийному номеру ТСД);
c) Освободить ресурсы и ждать следующих данных от ТСД;


По этому поводу я хотел бы узнать у форума какими способами лучше принимать данные из внешней программы - сервис в Axapta 3.0 и какими способами лучше передавать данные (обратный ответ) из Axapta 3.0 обратно внешней программы - сервис?
__________________
Axapta 3.0 SP6 Build 1951
Старый 21.03.2014, 17:37   #15  
ShkipeRR is offline
ShkipeRR
Участник
 
41 / 7 (1) +
Регистрация: 08.05.2013
Адрес: Владимир
Помогите реализовать в аксапте следущее:
в библиотеке CipherLabTCP.dll имеется функция следующего типа:

Наименование: GetProperties(SAFEARRAY **paParams, LONG * Result)
Вх. данные: paParams – Двумерный массив из 3 элементов типа (VARIANT).
Вых. Данные: 1 элемент — Порт; 2 элемент — (0 — писать в файл, 1 — генерировать
внещнее событие); 3 элемент — (1 — выводить отладочную информацию, 0 — не выводить отладочеую информацию);
Описание: Функция для получения свойств компоненты.
Возвращаемое значение: В случае успеха возвращает в Result двойной указатель на
SAFEARRAY, иначе 0
Как можно изобразить это в аксапте 3.0? Как я думаю нужно организовать двумерный массив из 3 элемента, но не знаю как это будет выглядеть на языке X ++, помогите разобраться?
__________________
Axapta 3.0 SP6 Build 1951
Старый 21.03.2014, 19:18   #16  
EVGL is offline
EVGL
Banned
Соотечественники
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
 
4,445 / 3001 (0) ++++++++++
Регистрация: 09.07.2002
Адрес: Parndorf, AT
Цитата:
Сообщение от gl00mie Посмотреть сообщение
PS. Хотя уже слабо верится, что на решение реальной задачи кто-то может отвести столько времени...
1 год, если не ошибаюсь
Феерично.
По крайней мере, автор перешел к активным действиям, т.е. программированию. Автор хочет соорудить что-то вроде listener, для чего на мой взгляд дилетанта разумнее всего было бы запрограммировать отдельный компонент ActiveX, встроить в форму AX 3.0 и подключить event-ы к коду X++.

Последний раз редактировалось EVGL; 21.03.2014 в 19:21.
Старый 04.03.2014, 11:53   #17  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5803 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
В 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   #18  
ShkipeRR is offline
ShkipeRR
Участник
 
41 / 7 (1) +
Регистрация: 08.05.2013
Адрес: Владимир
с void* всё верно. Описание функции нашёл
Название: int cipherlabtcpCreate(void** ptrtohandle)
Входные параметры:
- ptrtohandle (OUT) - указатель на дескриптор сервера-компоненты (дескриптор имеет тип
void*), который используется в последующих вызовах, может быть равен NULL. Значение
дескриптора должно быть инициализировано NULL.
Выходные параметры: код ошибки
Описание: Инициализация компоненты-объекта сервера .Создается объект-сервера. Если
ptrtohandle равен NULL, подразумевается использование одной "глобальной" компоненты-сервера.
__________________
Axapta 3.0 SP6 Build 1951
Старый 04.03.2014, 14:46   #19  
ShkipeRR is offline
ShkipeRR
Участник
 
41 / 7 (1) +
Регистрация: 08.05.2013
Адрес: Владимир
gl00mie
Как я понимаю если указатель на дескриптор, то нужно пользоваться ExtTypes::Pointer, а если входной параметр Int, то тут нужно задавать как ExtTypes:_Word (Дворд)?
__________________
Axapta 3.0 SP6 Build 1951
Старый 04.03.2014, 16:32   #20  
gl00mie is offline
gl00mie
Участник
MCBMSS
Most Valuable Professional
Лучший по профессии 2017
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,684 / 5803 (201) ++++++++++
Регистрация: 28.11.2005
Адрес: Москва
Записей в блоге: 3
Скажем так, если в качестве входного параметра API-функции нужно передать ссылку на область памяти, куда функция будет что-то писать, либо указатель на структуру данных, которую нужно сформировать из X++ с учетом того, что там нет работы с указателями, то надо указывать тип параметра ExtTypes::Pointer. В этом случае DLLFunction поймет, что соответствующий параметр, переданный из X++, надо передать дальше по ссылке. Если же параметр API-функции - просто значение некоего указателя (const void*), которое вызывающий код X++ получает извне, то для DLLFunction тип такого параметра можно указать как ExtTypes::DWord и передавать соотв. значение указателя как целое число.
За это сообщение автора поблагодарили: Logger (5), ShkipeRR (1).
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Ax3 and Win2008 для печати Arahnid DAX: Администрирование 13 22.04.2013 17:07
MSDAX 4.0 и планировщик win server 2008 werov2010 DAX: Администрирование 11 16.08.2012 14:18
Ruslan Goncharov: Scrolling in AX 3.0 without dll Blog bot DAX Blogs 0 09.03.2008 23:20
Help! DLL описание функции в аксапте ivas DAX: Программирование 16 27.04.2006 19:15
при вызове функции из своей DLL, вылетает ошибка Delfins DAX: Программирование 9 07.03.2006 19:29

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 06:10.