v8: Особенности dll, написанной на С++ #583435


#0 by Menjoy
Добрый день. Понадобилось написать компоненту с нуля на С++ (visual studio 2008). Был реализован основной интерфейс IInitDone, но dll не загружается 1Ской: Ошибка при вызове метода контекста (ЗагрузитьВнешнююКомпоненту): Ошибка при загрузке внешней компоненты Проект создан с поддержкой mfc. Кто сталкивался с написанием внешних компонент именно на с++ с нуля? Просьба подсказать, где могут быть подводные камни. За основу брал статью и уже готовую компоненту.
#1 by SnarkHunter
Видимо включен UAC...
#2 by Menjoy
можно чуть подробнее? Что это?
#3 by Menjoy
Уже прочитал в вики, все делается на win хр sp3
#4 by bezgudroman
А точно нужна именно внешняя компонента?
#5 by bezgudroman
Может вот так попробовать:
#6 by Menjoy
да, нужна именно внешняя. Ваша компонента тоже не подгружается 1С и в исходниках нужных интерфейсов и функций я не вижу. У вас работает?
#7 by bezgudroman
>> У вас работает? Конечно. Там же написано: "Сразу оговорюсь, в итоге получится обыкновенный inprocess server, а не "внешняя компонента" в понимании 1С. В этом примере не используется "Технология создания внешних компонент" от 1С (где-то она у меня на старом винте заблудилась - найти не могу), и поэтому описанная ниже технология подходит для задач типа "вы спрашиваете - мы отвечаем"."
#8 by bezgudroman
Что делает твоя ВК?
#9 by bezgudroman
тут попробуй:
#10 by Menjoy
компонента получает данные от 1С (сервер, порт, логин, пароль) и подключается к серверу, который в свою очередь постоянно передает данные компоненте, эти данные обрабатываются и уже в нужном виде попадают в 1С. Кхм, попробовал твою компоненту подключить как ЗагрузитьВнешнююКомпоненту("E:Example.dll"); предварительно зарегистрировав, та же ошибка.
#11 by Menjoy
Есть исходники уже рабочей компоненты, но без поддержки MFC. Поэтому решил создать проект с нуля, взял из предыдущего все обязательные интерфейсы и методы, все равно не подключает. p.s. а каким образом подключается эта компонента у тебя?
#12 by bezgudroman
В архиве есть файло: example.htm Там в конце написано:
#13 by Rie
v8 - имеется в виду 8.1 или 8.2?
#14 by Rie
+ И какую компоненту рисуешь: под NativeAPI или под COM?
#15 by Menjoy
v8 в моем случае 8.2 СОМ
#16 by Rie
Покажи реализацию IInitDone.
#17 by Rie
+ И ещё деталь - права на запись в реестр в HKEY_CLASSES_ROOT у пользователя есть?
#18 by Rie
+ Ну и ещё вопрос - а IDispatch реализован (хотя бы заглушками)?
#19 by orefkov
Никаких особенностей в длл на С++ нет. Реализуйте все правильно, и все будет работать. В ТВК пример на С++ есть. И что все у народа какие-то сложности с ВК? Делов то там - ПРАВИЛЬНО реализовать inproc server да пару интерфейсов. Ну и в реестре правильно описать.
#20 by Menjoy
права на запись в реестр есть, все записывается, искал в реестре по прогид. Реализация интерфейса IInitDone [        object, Методы упростил и сделал так, чтобы они только возвращали S_OK.
#21 by Menjoy
в реестре все прописывается правильно - CLSID и ProgID добавляются. Ошибка именно при вызове метода ЗагрузитьВнешнююКомпоненту; У меня у самого есть исходник внешней компоненты (которая у меня корректно работает), но без поддержки MFC, да и нужно научится просто создавать заготовку dll для 1С. А примера на С++ из ТВК не видел, выслать можете?
#22 by orefkov
Ну и скажи, каков ProgID твоей ВК ?
#23 by orefkov
+ Надеюсь, удовлетворяет вот этому: "При загрузке внешней компоненты функцией ЗагрузитьВнешнююКомпоненту 1С:Предприятие определяет ProgID OLE-объекта компоненты следующим образом: ProgID имеет вид <Vendor>.<Component>; в качестве первой части (<Vendor>) используется строка "AddIn"; в качестве второй части (<Component>) используется строка с ID 100 из таблицы строк компоненты. Cтрока может иметь вид "Name1|Name2|...|NameN", и в этом случае будут созданы все объекты с ProgID вида "AddIn.NameX". Если такая строка отсутствует, то используется имя файла внешней компоненты без расширения."
#24 by Rie
Это не _реализация_, это _описание_ интерфейса. Что касается "упростил" - то метод GetInfo должен не только вернуть S_OK, но и правильное значение версии установить.
#25 by Menjoy
ProgID следующий - com_1c.TSoc.1 - такой прописался в реестре. А <vendor> обязательно должен быть "AddIn". Если так, то возможно именно в этом проблема, проверю. GetInfo так же пробовал использовать из рабочего исходника.
#26 by Rie
Ещё обрати внимание на ресурс 100.
#27 by orefkov
Смени прогид на "Addin.ИмяТвоегоФайлаБезРасширения"
#28 by Menjoy
Теперь, судя по всему ЗагрузитьВнешнююКомпоненту; срабатывает, ошибки нет. Но не создается объект - ВК = Новый ("AddIn.AddInSoc"); Ошибка - Тип не определен (AddIn.SocDll). ProgID (независимый от версии) в реестре прописан такой же, пробовал и с AddIn.SocDll.1
#29 by Rie
Что в ресурсе 100? Какой ProgID в реестре?
#31 by Menjoy
Под ID 100 лежит AddInSoc В реестре AddIn.AddInSoc
#33 by Rie
Новый COMОбъект("AddIn.AddInSoc")?
#34 by Menjoy
В сообщение кое что перепутал, там везде AddIn.AddInSoc вместо SocDll
#36 by Menjoy
Ошибка при вызове конструктора (COMОбъект): Интерфейс не поддерживается: Интерфейс не поддерживается При таком подходе, получается что интерфейс какой-то не реализован просто. В этой длл есть только IInitDone и все. Кстати, исходник, который у меня есть, его длл подключается через Новый (""); т.е. без COMОбъект.
#37 by Rie
Заглушка IDispatch есть? И как именно сейчас выглядит GetInfo?
#39 by Menjoy
А что за заглушка IDispatch?
#40 by Rie
Реализовать IDispatch - пусть его методы просто возвращают E_NOTIMPL.
#41 by Menjoy
Он же реализован по умолчанию.    {    public:        virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(        virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(            /* [in] */ __RPC__in REFIID riid,
#42 by Rie
Твой код я не вижу, а телетяпией не страдаю :-) Какой интерфейс не реализован - вероятно, ILanguageExtender.
#43 by Menjoy
Да-да, именно, только что сам к этому пришел - ILanguageExtender. Подгрузил другую компоненту как СОМ и увидел, что она вернула два значения: Отсюда и понял )) Спасибо, пожалуй займусь в рабочий день.
#44 by orefkov
ILanguageExtender надо
#45 by Menjoy
а если будет реализован ILanguageExtender сработает ли просто ВК = Новый ("ProgID")?
#46 by Rie
Новый COMОбъект("ProgID")
#47 by Rie
+ Хотя нет. Тут я соврал насчёт COMОбъект.
#48 by Menjoy
немного не понял :) Есть исходники компоненты, на которую я полагался в своей разработке, так вот она вызывается просто как Новый("ProgID") и получается ком-объект, проверял в отладчике.
#49 by Rie
Я и говорю - соврал я насчёт того, что надо писать именно Новый COMОбъект.
#50 by Rie
+ Ты б поставил в методах IInitDone и ILanguageExtender вызовы MessageBox - и сразу стало бы ясно, на каком этапе у тебя проблемы.
#51 by Menjoy
Займусь дальше только в понедельник ;) Если что, то буду продолжать тему )) Не нашел подобных на просторах интернета, потому и начал свою. Спасибо за совет на счет MessageBox, попробую.
#52 by Rie
Если действовать "строго по инструкции", соблюдая все требования - проблем не будет. Проверено :-)
#53 by Menjoy
По-тиху продвигаюсь вперед и возник такой вопрос. Как правильно создается внешнее событие? Сделал спец. функцию и повесил ее на кнопку в 1С, чтобы тренироваться. Функция в срр имеет следующий вид: VOID CALLBACK Connection(CString value1, CString value2) { Но внешнее событие не ловится формой :( В модуле формы 1С прописано: Процедура ВнешнееСобытие(Источник, Событие, Данные) При отладке value1 задаю 1.
#54 by Menjoy
При отладке еще выловил такую ошибку: Unhandled exception at 0x06375e01 (AddInCOM.dll) in 1cv8.exe: 0xC0000005: Access violation reading location 0x00000000.
#55 by Rebelx
а может ну ее эту компоненту? что нельзя сделать на 1С? а еще можно использовать JS для бинарных данных
#56 by Menjoy
нужно, возможностей куча, к тому же с++ быстрее обрабатывает информацию ;) Меня больше интересует ответ на вопрос, нежели споры о полезности компонент)
#57 by Serginio1
Возьми отсюда Исходник ВК которая загружает Объект Автоматизации поддерживающий ITypeInfo и выполняет все его свойства и методы через IlanguageExtender. Где там есть еще и исходники аналогичной приблуды на C++
#58 by Menjoy
то, что вы скинули - на delphi И все же хочется найти ошибку у себя.
#59 by Serginio1
#60 by jsmith82
я пишу на остром си - всё без проблем
#61 by Rie
Эта ошибка произошла в коде на С++! Там её и надо искать, сам механизм внешних компонент тут ни при чём. Поставь отладочный вывод. Определи, в какой строке происходит исключение. Или перехвати его try ... catch - и выдай результат. Где вызывается Connection - никому, кроме тебя не известно. Что за значения у каких переменных - тоже.
#62 by Menjoy
Connection вызываю из 1С, он доступен через внешнюю компоненту. Ошибку выдает именно в этой строке: Думаю, что может быть связано с строкой в срр файле: static IAsyncEvent *pAsyncEvent = NULL;
#63 by Rie
Нет, ну трах-тибидох! Естественно с этим связано!!! Обращаться к методу объекта по указателю NULL - это круто! pAsyncEvent инициализируй в IInitDone::Init.
#64 by Menjoy
Ошибка при вызове любого из методов pAsyncEvent.
#65 by Menjoy
извиняюсь за такие вопросы, но я пару дней как вижу С++ ;)
#66 by Rie
Меня это не удивляет. Когда вызываются методы объекта по указателю NULL - так всегда бывает.
#67 by Rie
Тогда зря ты сел за написание на нём ВК. Лучше освой язык - а потом уже пиши.
#68 by Menjoy
а каким образом правильно инициализировать pAsyncEvent в IInitDone::Init? в данном контексте просто не ясно, что значит инициализовать
#69 by Rie
При помощи GetInterface получить IAsyncEvent из того IDispatch, который тебе в Init передан.
#70 by Menjoy
Упс, было очень поспешным. Действительно, нужно было просто добавить строку pAsyncEvent = m_iAsyncEvent; в объявлении метода Connection. Т.к. в IInitDone::Init инициализирован:
#71 by Menjoy
согласен конечно с замечанием про подучить язык, но так обучаться интереснее. К тому же мне нужно изучить всего лишь некоторые аспекты языка :) Тем не менее, спасибо за уже оказанную помощь и что тему поглядываешь ))
#72 by Rie
Если у тебя уже есть член с именем m_iConnect (а судя по префиксу m_ - это именно член) - зачем ещё static-переменную заводить?
#73 by Menjoy
вот уж не знаю, она объявлена была в исходниках, по-немногу разгребаюсь с ними :)
#74 by Menjoy
Пытаюсь сделал возвращаемое функцией значение, причем не булево, а допустим результат сложения двух чисел. Может кто пример описания метода в HRESULT CallAsFunc(long lMethodNum, VARIANT *pRetValue, SAFEARRAY**pVars) показать?
#75 by orefkov
#76 by Menjoy
спасибо. Сейчас буду учиться возвращать результат выполнения другой функции, тут уже по срр нужно читать.
Тэги: 1С 8
Ответить:
Комментарии доступны только авторизированным пользователям

В этой группе 1С