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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 27.04.2006, 12:35   #1  
ivas is offline
ivas
Участник
Аватар для ivas
 
252 / 68 (3) ++++
Регистрация: 22.12.2005
:( Help! DLL описание функции в аксапте
Доброго всем времени суток
есть DLL с заголовком на С. Требуется произвести вызов из аксапты. Проблема в том, что не работает.
На С прототип выглядит так:
Код:
 
ISC_STATUS  ISC_EXPORT isc_attach_database (ISC_STATUS ISC_FAR *,
                        short,
                        char ISC_FAR *,
                        isc_db_handle ISC_FAR *,
                        short,
                        char ISC_FAR *);
Он проинтерпритирован так:

Код:
   
isc_attach_database = new DllFunction(GDS32, "isc_attach_database");
isc_attach_database.returns(ExtTypes::DWord);
isc_attach_database.arg(ExtTypes::Pointer,
                            ExtTypes::Word,
                            ExtTypes::String,
                            ExtTypes::Pointer,
                            ExtTypes::Word,
                            ExtTypes::String);
вызов на С:
Код:
 
isc_db_handle DB;
ISC_STATUS  status_vector[20];
short   dpb_buf_len=20;
char dpb_buf[]={
    isc_dpb_version1,  //версия буфера 
    isc_dpb_user_name,  //начинается кластер параметра имя пользователя
    6,     //длина этого параметра 6 байт
    'S','Y','S','D','B','A',                //строка имени пользователя
    isc_dpb_password,  //начинается кластер пароля пользователя
    9,     //длина его 9 байт
    'm','a','s','t','e','r','k','e','y' //сам пароль
    };
 
isc_attach_database(status_vector, strlen(str), str, &DB,dpb_buf_len,dpb_buf));
Запускается, но не работает в аксапте. выдает код, означающий Invalid DB handle. Другие ф-ии из этой же DLL работают нормально. Под С все работает.... %(

Подскажите, плз, в чем грабли...
Старый 27.04.2006, 12:58   #2  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от ivas
Код:
isc_attach_database(status_vector, strlen(str), str, &DB,dpb_buf_len,dpb_buf));
Во-первых, я не знаю что означает конструкция &DB в Аксапте.
В Аксапте, как и в Java нет операции взятия адреса.
Это принципиальное отличие джавы от C.

Во-вторых, чтобы передать область памяти нельзя использовать аксаптовский массив.
Массив в Аксапте намного более сложная штука, чем кажется.
Читайте доку.
Чтобы передавать параметры наружу лучше использовать SafeArray.
Он же используется для работы с Variant.
Опять же поищите доку и примеры использования в семействе классов tutorial*
__________________
полезное на axForum, github, vk, coub.
Старый 27.04.2006, 13:10   #3  
ivas is offline
ivas
Участник
Аватар для ivas
 
252 / 68 (3) ++++
Регистрация: 22.12.2005
Цитата:
Цитата:
Сообщение от ivas
Код:
isc_attach_database(status_vector, strlen(str), str, &DB,dpb_buf_len,dpb_buf));



Во-первых, я не знаю что означает конструкция &DB в Аксапте.
это код на С ...

в аксапте инициализируем как DB = new Binary(4);
Старый 27.04.2006, 13:18   #4  
ivas is offline
ivas
Участник
Аватар для ivas
 
252 / 68 (3) ++++
Регистрация: 22.12.2005
в аксапте вызываем так:
Код:
 
isc_attach_database.call(status, strlen(DB_name), DB_name, DB, 20, dpb))
где:
Код:
 
  Binary status       = new Binary(80);
  Binary dpb          = new Binary(20);

  dpb.byte(0, #isc_dpb_version1);
  dpb.byte(1, #isc_dpb_user_name);
  dpb.byte(2, 6);
  dpb.string(3, 'SYSDBA');
  dpb.byte(9, #isc_dpb_password);
  dpb.byte(10, 9);
  dpb.string(11, 'MASTERKEY');
к стати DLL осуществляет доступ п бд InterBase...
Старый 27.04.2006, 13:29   #5  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,472 / 4494 (208) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
Цитата:
Сообщение от ivas
это код на С ...

в аксапте инициализируем как DB = new Binary(4);
Понял. Извините.
Тогда непонятно.

Посмотрите, например, классы
WinAPI
WinAVI
ChartFX
BarCode и его потомков
HeapLog
чтобы увидеть примеры использования.
__________________
полезное на axForum, github, vk, coub.
Старый 27.04.2006, 13:48   #6  
ivas is offline
ivas
Участник
Аватар для ivas
 
252 / 68 (3) ++++
Регистрация: 22.12.2005
в общем стоит задача подключиться к бд InterBase и при этом получить курсор который можно апдейтить
стандартное подключение с помощью odbc драйвера работает, но при попытке апдейта курсора система говорит
Цитата:
Метод 'Update' в COM-объекте класса '_Recordset' возвратил код ошибки 0x800A0CB3 (<неизвестно>), который означает:
Текущий объект Recordset не поддерживает обновление. Это связано с ограничением поставщика или с выбранным типом блокировки.
однако есть класс: \Classes\DSORecordset
в котором определена масса методов работы с курсором и подключение можно выполнить через ODBC драйвер.
Может кто подскажет как использовать эти классы с префиксом DSO их структура оч. похожа на CCADOConnection, CCADORecordset

Последний раз редактировалось ivas; 27.04.2006 в 13:52.
Старый 27.04.2006, 14:44   #7  
Recoilme is offline
Recoilme
злыдень
Аватар для Recoilme
Злыдни
 
895 / 192 (8) ++++++
Регистрация: 18.06.2003
Какой драйвер? Gemini ?
__________________
Ибо зло есть лучшая сила человека. "Человек должен становиться все лучше и злее" -- так учу я. /Ф. Ницше/
Старый 27.04.2006, 15:52   #8  
ivas is offline
ivas
Участник
Аватар для ivas
 
252 / 68 (3) ++++
Регистрация: 22.12.2005
драйвер firebird
и gemini тоже есть
оба работают...
вопрос в апдейте указателя
Старый 27.04.2006, 15:56   #9  
Recoilme is offline
Recoilme
злыдень
Аватар для Recoilme
Злыдни
 
895 / 192 (8) ++++++
Регистрация: 18.06.2003
Лови..
PHP код:
static void ip_vkul_testado(Args _args)
{
    
#CCADO
    
CCADOConnection cn = new CCADOConnection() ;
    
CCADORecordset          adoRecordset  = new CCADORecordset();
    
InventTable             inventTable;
    
DKL_InventTable         dklinventTable;
    
DKL_BaseRetailPrices    baseprice;
    
DKL_InventClassVarTable invclass;
    
VendTable               vendor;
    
CustTable               cust;
    
DKL_BrandTable          brand;
    
InventLocation          sklad;
    
str     descr;
    
int     KATEGORIAKOD,GRUPPAKOD,PODGRUPPAKOD,countrec,recCnt,skltype;
    
real    maksskidka,koefret;
    
int     bool,bool2,i,vendorid;
    
Map     invClassId = new map(Types::StringTypes::Integer);
    
SysOperationProgress progr  = new SysOperationProgress();
    ;
    
cn = new CCADOConnection();
    
select count(recidfrom invclass;
    
select count(recidfrom vendor;
    
select count(recidfrom cust;
    
select count(recidfrom brand;
    
select count(recidfrom inventTable;
    
select count(recidfrom dklinventTable;
    
select count(recidfrom baseprice;
    
recCnt invclass.RecId vendor.RecId cust.RecId brand.RecId inventTable.RecId dklinventTable.RecId baseprice.RecId;
    
cn.open("Provider=MSDASQL.1;Persist Security Info=False;User ID=sysdba;Data Source=iptmp");
    
/*
    progr.setTotal(recCnt);
    progr.setCaption('?????????????');

    //?????????????
    while select invclass
    {
        progr.incCount();
        invClassId.insert(invClass.InventClassVarId,invClass.RecId);
        descr = strdel(invclass.Description,55,200);
        maksskidka = invclass.DiscLimit / 100;
        koefret = invclass.RetailPricePctKoeff / 100;
        if (invclass.LMA_LevelNum == 1)
        {
            adoRecordset  = new CCADORecordset();
            adoRecordset.open(strfmt("select id from z_kategoria where id = %1",CNN::quoted(invclass.RecId)),cn, #adOpenForwardOnly, #adLockReadOnly);
            if (adoRecordset.EOF())
                cn.execute(strfmt("INSERT INTO Z_KATEGORIA (KATEGORIA,ID,KOEFPRODAJ,MAKSSKIDKA) VALUES (%1,%2,%3,%4)",CNN::quoted(Descr),CNN::quoted(invclass.RecId),CNN::quoted(koefret),CNN::quoted(maksskidka)));
            else
                cn.execute(strfmt("UPDATE Z_KATEGORIA SET KATEGORIA=%1,KOEFPRODAJ=%3,MAKSSKIDKA=%4 WHERE ID = %2",CNN::quoted(Descr),CNN::quoted(invclass.RecId),CNN::quoted(koefret),CNN::quoted(maksskidka)));
            adoRecordset.close();
        }

        if (invclass.LMA_LevelNum == 2)
        {
            adoRecordset  = new CCADORecordset();
            adoRecordset.open(strfmt("select id from Z_GRUPPA where id = %1",CNN::quoted(invclass.RecId)),cn, #adOpenForwardOnly, #adLockReadOnly);
            if (adoRecordset.EOF())
                cn.execute(strfmt("INSERT INTO Z_GRUPPA (GRUPPA,ID,KOEFPRODAJ,MAKSSKIDKA) VALUES (%1,%2,%3,%4)",CNN::quoted(Descr),CNN::quoted(invclass.RecId),CNN::quoted(koefret),CNN::quoted(maksskidka)));
            else
                cn.execute(strfmt("UPDATE Z_GRUPPA SET GRUPPA=%1,KOEFPRODAJ=%3,MAKSSKIDKA=%4 WHERE ID = %2",CNN::quoted(Descr),CNN::quoted(invclass.RecId),CNN::quoted(koefret),CNN::quoted(maksskidka)));
            adoRecordset.close();
        }

        if (invclass.LMA_LevelNum == 3)
        {
            adoRecordset  = new CCADORecordset();
            adoRecordset.open(strfmt("select id from Z_PODGRUPPA where id = %1",CNN::quoted(invclass.RecId)),cn, #adOpenForwardOnly, #adLockReadOnly);
            if (adoRecordset.EOF())
                cn.execute(strfmt("INSERT INTO Z_PODGRUPPA (PODGRUPPA,ID,KOEFPRODAJ,MAKSSKIDKA) VALUES (%1,%2,%3,%4)",CNN::quoted(Descr),CNN::quoted(invclass.RecId),CNN::quoted(koefret),CNN::quoted(maksskidka)));
            else
                cn.execute(strfmt("UPDATE Z_PODGRUPPA SET PODGRUPPA=%1,KOEFPRODAJ=%3,MAKSSKIDKA=%4 WHERE ID = %2",CNN::quoted(Descr),CNN::quoted(invclass.RecId),CNN::quoted(koefret),CNN::quoted(maksskidka)));
            adoRecordset.close();
        }

    }

    progr.setCaption('??????????');
    //??????????
    while select vendor 
__________________
Ибо зло есть лучшая сила человека. "Человек должен становиться все лучше и злее" -- так учу я. /Ф. Ницше/
Старый 27.04.2006, 15:57   #10  
Recoilme is offline
Recoilme
злыдень
Аватар для Recoilme
Злыдни
 
895 / 192 (8) ++++++
Регистрация: 18.06.2003
Не влез гад..
Это через джемини и CCAdo

PHP код:
    progr.setTotal(recCnt);
    
progr.setCaption('?????????????');

    
//?????????????
    
while select invclass
    
{
        
progr.incCount();
        
invClassId.insert(invClass.InventClassVarId,invClass.RecId);
        
descr strdel(invclass.Description,55,200);
        
maksskidka invclass.DiscLimit 100;
        
koefret invclass.RetailPricePctKoeff 100;
        if (
invclass.LMA_LevelNum == 1)
        {
            
adoRecordset  = new CCADORecordset();
            
adoRecordset.open(strfmt("select id from z_kategoria where id = %1",CNN::quoted(invclass.RecId)),cn#adOpenForwardOnly, #adLockReadOnly);
            
if (adoRecordset.EOF())
                
cn.execute(strfmt("INSERT INTO Z_KATEGORIA (KATEGORIA,ID,KOEFPRODAJ,MAKSSKIDKA) VALUES (%1,%2,%3,%4)",CNN::quoted(Descr),CNN::quoted(invclass.RecId),CNN::quoted(koefret),CNN::quoted(maksskidka)));
            else
                
cn.execute(strfmt("UPDATE Z_KATEGORIA SET KATEGORIA=%1,KOEFPRODAJ=%3,MAKSSKIDKA=%4 WHERE ID = %2",CNN::quoted(Descr),CNN::quoted(invclass.RecId),CNN::quoted(koefret),CNN::quoted(maksskidka)));
            
adoRecordset.close();
        }

        if (
invclass.LMA_LevelNum == 2)
        {
            
adoRecordset  = new CCADORecordset();
            
adoRecordset.open(strfmt("select id from Z_GRUPPA where id = %1",CNN::quoted(invclass.RecId)),cn#adOpenForwardOnly, #adLockReadOnly);
            
if (adoRecordset.EOF())
                
cn.execute(strfmt("INSERT INTO Z_GRUPPA (GRUPPA,ID,KOEFPRODAJ,MAKSSKIDKA) VALUES (%1,%2,%3,%4)",CNN::quoted(Descr),CNN::quoted(invclass.RecId),CNN::quoted(koefret),CNN::quoted(maksskidka)));
            else
                
cn.execute(strfmt("UPDATE Z_GRUPPA SET GRUPPA=%1,KOEFPRODAJ=%3,MAKSSKIDKA=%4 WHERE ID = %2",CNN::quoted(Descr),CNN::quoted(invclass.RecId),CNN::quoted(koefret),CNN::quoted(maksskidka)));
            
adoRecordset.close();
        }

        if (
invclass.LMA_LevelNum == 3)
        {
            
adoRecordset  = new CCADORecordset();
            
adoRecordset.open(strfmt("select id from Z_PODGRUPPA where id = %1",CNN::quoted(invclass.RecId)),cn#adOpenForwardOnly, #adLockReadOnly);
            
if (adoRecordset.EOF())
                
cn.execute(strfmt("INSERT INTO Z_PODGRUPPA (PODGRUPPA,ID,KOEFPRODAJ,MAKSSKIDKA) VALUES (%1,%2,%3,%4)",CNN::quoted(Descr),CNN::quoted(invclass.RecId),CNN::quoted(koefret),CNN::quoted(maksskidka)));
            else
                
cn.execute(strfmt("UPDATE Z_PODGRUPPA SET PODGRUPPA=%1,KOEFPRODAJ=%3,MAKSSKIDKA=%4 WHERE ID = %2",CNN::quoted(Descr),CNN::quoted(invclass.RecId),CNN::quoted(koefret),CNN::quoted(maksskidka)));
            
adoRecordset.close();
        }

    } 
__________________
Ибо зло есть лучшая сила человека. "Человек должен становиться все лучше и злее" -- так учу я. /Ф. Ницше/
Старый 27.04.2006, 16:02   #11  
Lucky13 is offline
Lucky13
Участник
1C
 
714 / 198 (8) ++++++
Регистрация: 21.10.2004
А почему у Вас последний параметр в C объявлен как char*, в Ax ExtTypes::string, а передается Binary(20)? Axpata так не въедет. Нужно либо объявлять как ExtTypes::Pointer, либо передавать как string
Старый 27.04.2006, 16:15   #12  
ivas is offline
ivas
Участник
Аватар для ivas
 
252 / 68 (3) ++++
Регистрация: 22.12.2005
спасибо заответ, но имелось в виду несколько другое у тебя апдейт происходит с помощью явно заданного sql запроса, это мы делать умеем
необходимо нечто вроде этого:
Код:
 
    command.activeConnection(cn);
    command.commandText("select * from goods");
    rs = command.execute();
    while (!rs.eof())
    {
        rs.recordSet().Update(2, "aaaa"); 
        rs.moveNext();
    }
Цитата:
А почему у Вас последний параметр в C объявлен как char*, в Ax ExtTypes::string, а передается Binary(20)? Axpata так не въедет. Нужно либо объявлять как ExtTypes::Pointer, либо передавать как string
согласен баг, это просто от перебора вариантов остатки
сейчас выдает ошибку idc_login тоесть видимо жрет последний параметр но неможет его развернуть
пробовали и как pointer
и как dpb.string(0) (в первом варианте)
не работает...
Старый 27.04.2006, 16:36   #13  
ivas is offline
ivas
Участник
Аватар для ivas
 
252 / 68 (3) ++++
Регистрация: 22.12.2005
косяк нашли
вот в этой строке:
PHP код:
dpb.string(11'MASTERKEY'); 
а нужно было
PHP код:
dpb.string(11'masterkey'); 
всем спасибо
Старый 27.04.2006, 16:42   #14  
Recoilme is offline
Recoilme
злыдень
Аватар для Recoilme
Злыдни
 
895 / 192 (8) ++++++
Регистрация: 18.06.2003
?
Ты добился обновляемого резалтсета??? Драйвера ж его не поддерживают!, во всяком случае джемини...
__________________
Ибо зло есть лучшая сила человека. "Человек должен становиться все лучше и злее" -- так учу я. /Ф. Ницше/
Старый 27.04.2006, 16:57   #15  
ivas is offline
ivas
Участник
Аватар для ivas
 
252 / 68 (3) ++++
Регистрация: 22.12.2005
Мы подключили базу с помощью DLL. %)))
Кстати, почему
Цитата:
Драйвера ж его не поддерживают!, во всяком случае джемини...
?
А как себя ведет FireBird?
И что на счет классов DSO*, в частности DSORecordset? Там же есть поддержка курсора на обновление и т.д..... а оно должно работать с любым ODBC драйвером...
Старый 27.04.2006, 17:05   #16  
Recoilme is offline
Recoilme
злыдень
Аватар для Recoilme
Злыдни
 
895 / 192 (8) ++++++
Регистрация: 18.06.2003
Дело не в СУБД и не в классах. Сами драйвера не позволяют. Обсуждалось например здесь
Аксапта в качестве клиента для фаербёрда - это прикольно , туда ей и место
__________________
Ибо зло есть лучшая сила человека. "Человек должен становиться все лучше и злее" -- так учу я. /Ф. Ницше/
Старый 27.04.2006, 19:15   #17  
sukhanchik is offline
sukhanchik
Administrator
Аватар для sukhanchik
MCBMSS
Злыдни
Лучший по профессии 2015
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
3,323 / 3547 (125) ++++++++++
Регистрация: 13.06.2004
Адрес: Москва
Есть рабочий примерчик.... Но правда как было верно подмечено на sql.ru - работает на Access. Не проверял на других БД.
X++:
// Экспорт из Axapta через ADO в другую базу данных заданной таблицы
static void tutorial_WriteADO(Args _args)
{
    CCADOConnection cn      = new CCADOConnection();
    CCADOCommand    command = new CCADOCommand();
    CCADORecordset  rcs;
    Str connectionString;
    str            tableName = "VENDTABLE";
    FilePath       filePath  = "D:\\zz.mdb";
    anytype        newValue;
    #CCADO
    ;
    connectionString =  'Provider=Microsoft.Jet.OLEDB.4.0;';
    connectionString += 'Data Source=' + filePath + ';';
    connectionString += 'Mode=ReadWrite;';
    connectionString += 'Persist Security Info=False';

    cn.open(connectionString);

    rcs = new CCADORecordset();
    rcs.open(tableName, cn, #adOpenKeyset, #adLockOptimistic, #adCmdTable);
    rcs.addNew();
    for (i = 1; i <= rcs.fields().count(); i++)
    {
        rcs.fields().itemIdx(i - 1).setValue(newValue);
    }
    rcs.update(); 
}
Для работы этого примера нужно добавить в класс CCADORecordset
методы:
X++:
void addNew()
{
    recordSet.AddNew();
}
void update()
{
    recordSet.update();
}
А в класс CCADOField - метод
X++:
// Установка значения (real, date, int, str)
void setValue(anytype _value)
{
    switch (typeof(_value))
    {
        case Types::Date:
            field.value(COMVariant::createFromDate(_value));
            break;
        case Types::Enum, Types::Integer:
            field.value(COMVariant::createFromInt(_value));
            break;
        case Types::Real:
            field.value(COMVariant::createFromReal(_value));
            break;
        case Types::RString, Types::String, Types::VarString:
            field.value(COMVariant::createFromStr(_value));
            break;
        default:
            field.value(COMVariant::createNoValue());
    }
}
Хочу также отметить тот факт, что в ADO методы AddNew/Edit работают исключительно напрямую с таблицами (вариант SELECT * FROM Таблица не катит).
Поэтому обновляемые рекордсеты не сильно распространены. Гораздо гибче и удобнее SQL - операторы UPDATE, INSERT, DELETE
__________________
Возможно сделать все. Вопрос времени

Последний раз редактировалось sukhanchik; 27.04.2006 в 19:22.
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
Проблема с самописной DLL. VAlek DAX: Программирование 18 28.12.2008 10:37
Client Axapta 3.0 SP4 и Linux. Как запустить? Daiver DAX: Администрирование 10 28.06.2007 15:59
Вызов экспортируемой функции DLL Jabberwocky DAX: Программирование 8 12.09.2006 17:20
при вызове функции из своей DLL, вылетает ошибка Delfins DAX: Программирование 9 07.03.2006 19:29
Описание кода в Аксапте vasiliy DAX: Прочие вопросы 5 23.03.2005 12:16
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

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

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