SAP R/3 форум ABAP консультантов
Russian ABAP Developer's Club

Home - FAQ - Search - Memberlist - Usergroups - Profile - Log in to check your private messages - Register - Log in - English
Blogs - Weblogs News

работа с внешней библиотекой, OLE2


Goto page 1, 2  Next
 
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> ABAP
View previous topic :: View next topic  
Author Message
rudeman
Специалист
Специалист



Joined: 21 Sep 2007
Posts: 55
Location: Киев

PostPosted: Fri Sep 21, 2007 12:50 pm    Post subject: работа с внешней библиотекой, OLE2 Reply with quote

Добрый день! Помогите пожалуйста с такой проблемой.
Необходимо достучаться из R/3 к внешней библиотеке. Но библиотека не зарегистрирована и не регистрируется в системе.
Т.е. просто прописать в транзакции SOLE (таблице TOLE) не получаетсяю. Можно ли как-то вызывать из ABAPa функции этой внешней библиотеки?
Заранее - сделать из библиотеки некий *.exe не подходит... нада чтоб библиотека загружалась именно в области памяти R/3... изза "соображений безопасности начальства".
Буду очнеь благодарен за советы.
Back to top
View user's profile Send private message
admin
Администратор
Администратор



Joined: 01 Sep 2007
Posts: 1640

PostPosted: Fri Sep 21, 2007 2:21 pm    Post subject: Reply with quote

Библиотека, о который Вы говорите, вероятней всего представляет из себя dll под Windows.
Из SAP возможен доступ только к ActiveX объектам, поддерживающим интерфейс обмена OLE2. Поэтому напрямую обратиться к этой библиотеке не получится, необходимо писать некий ActiveX контейнер, который загрузит dll и будет предоставлять (транслировать) методы dll в методы ActiveX. Без этого вряд ли обойдетесь.

То что начальство предлагает загружать dll в область памяти SAP - это, на мой взгляд маловероятно, потому что эта библиотека, даже обернутая в ActiveX, будет выполняться на Презентационном сервере (рабочей станции пользователя), а SAP пространство распределено на Сервере Приложений и их не совместить.
Back to top
View user's profile Send private message
rudeman
Специалист
Специалист



Joined: 21 Sep 2007
Posts: 55
Location: Киев

PostPosted: Thu Oct 04, 2007 9:25 am    Post subject: Reply with quote

А где можно почитать про "оборачивание"? Потому как задача стоит именно в таком ракурсе... (

Last edited by rudeman on Mon Oct 08, 2007 12:12 pm; edited 1 time in total
Back to top
View user's profile Send private message
admin
Администратор
Администратор



Joined: 01 Sep 2007
Posts: 1640

PostPosted: Thu Oct 04, 2007 10:17 am    Post subject: Reply with quote

Во первых нужно знать, на каком языке будете писать?
Общий план такой:
1) Создаете контейнер ActiveX c набором необходимых интерфеймов, соотвествующих необходимым методам из dll. Выходной модуль будет иметь расширение OCX.
2) Загружаете dll в память программы и реализуете в программе преобразование вызовов ActiveX методов в вызовы методов dll
Загрузка dll в WinAPI c помощью функции LoadLibrary
Пример: http://www.firststeps.ru/mfc/winapi/r.php?41
3) Регистрация Activex на Windows
C:\Windows\system32\regsvr32.exe myprog1.OCX

Примеры разработок ActiveX на сайтах:
http://www.firststeps.ru
http://msdn.microsoft.com
http://help.sap.com/saphelp_46c/helpdata/de/77/39594b622f11d2804b00c04fada2a1/frameset.htm - SAP Automation
Пример в SAP - программа TEST_CONTAINERS

После готовности OCX вызывайте его как описано в примере. Здесь используется другой ActiveX элемент, замените названия и входные параметры:

This tip works like the MS Word spell checker. The code has been tested in 4.6C on Windows 2000 and Windows XP machines. For this program to work you should have Microsoft Word installed on your machine.

STEP A.
1. Download the file ( Testspellchk.zip) from this link:
http://www.geocities.com/athavan_raja/Testspellchk.zip
2. Unzip the file (Testspellchk.ocx) to your desktop.
3. Register the control. To register start„»run and in the dialog box type in regsvr32.exe and then drag and drop the file (Testspellchk.ocx) you saved onto your desktop in the dialog box and click OK. You will get a message that the registration is successful.

STEP B.
Create a Function module as follows:
a. Import parameter IN_WORD type string
b. Export parameter OUT_WORD TYPE STRING
c. Exception CNTL_ERROR.

Copy and paste the below given code to the Global Data of the function module:

Code:
class cl_spell definition
inheriting from cl_gui_control .

public section .

methods:
constructor
importing
!parent type ref to cl_gui_container
value(shellstyle) type i optional
value(disp_mode) type i optional
value(life_time) type i optional
value(name) type string optional
exceptions
cntl_error
cntl_install_error .

methods:
spellcheck
importing
wf_string type any optional
exporting
result type any .

endclass .

data: wf_rstring(120) ,
wf_len type i .
data: spell_checker type ref to cl_spell ,
my_container type ref to cl_gui_custom_container,
wf_t(120) ,
this_repid like sy-repid .

********implementation
class cl_spell implementation .

method constructor.

data: ctrl_name(80) type c ,
wf_clsid(100) type c .

if not cl_gui_object=>activex is initial .
wf_clsid = 'Testspellchk.spellchkctrl' .
else .
raise cntl_error .
endif .

call method super->constructor

exporting
clsid = wf_clsid
shellstyle = shellstyle
lifetime = life_time
name = name
parent = parent
exceptions
cntl_system_error = 1
others = 2 .

case sy-subrc .
when 1 .
raise cntl_install_error .
when 2 .
message w398(00) with 'Control Error' .

endcase .

endmethod .

method spellcheck .
clear wf_rstring .
call method me->call_method
exporting
method = 'SpellCheck'
p1 = wf_string
p_count = 1
queue_only = ' '
importing
result = wf_rstring .

call method cl_gui_cfw=>flush
exceptions cntl_system_error = 1
cntl_error = 2.

if sy-subrc ne 0 .
message w398(00) with 'Control Error' .
endif .
endmethod .

endclass .

Create a screen for the program and place a CUSTOM CONTROL on to the screen and name it OUTPUT_CONTAINER.

Enter the below given code into the Function Module.


Code:
FUNCTION Y_SPELL_CHECK.
*"----------------------------------------------------------------------
*"*"Local interface:
*"  IMPORTING
*"     VALUE(IN_WORD) TYPE  STRING
*"  EXPORTING
*"     VALUE(OUT_WORD) TYPE  STRING
*"  EXCEPTIONS
*"      CNTL_ERROR
*"----------------------------------------------------------------------



 if my_container is initial.
    create object my_container
        exporting
            container_name = 'OUTPUT_CONTAINER'
        exceptions
            others = 1.
    case sy-subrc.
      when 0.
      when others.
        raise cntl_error.
    endcase.
  endif .

  if spell_checker is initial.


    create object spell_checker
         exporting
              parent    = my_container .

    if sy-subrc ne 0.
      raise cntl_error.
    endif.
  endif .



  call method spell_checker->spellcheck
      exporting wf_string = in_word
      importing result = wf_rstring .


if not wf_rstring is initial .
clear wf_t .
clear wf_len .
wf_len = strlen( wf_rstring ) .
wf_len = wf_len - 1 .

wf_t = wf_rstring .
wf_t+wf_len(1) = ' ' .
out_word = wf_t .
endif .


if not spell_checker is initial .
        call method spell_checker->free.
        free spell_checker .
      endif .
      if not my_container is initial .
        call method my_container->free.
        free my_container .
      endif .

ENDFUNCTION.

Note: When you call this function module with a wrongly spelled word as input you will get a pop up like word for change/ignore the word.

If changed, the FM returns the changed word else it returns the original word.
Back to top
View user's profile Send private message
rudeman
Специалист
Специалист



Joined: 21 Sep 2007
Posts: 55
Location: Киев

PostPosted: Mon Oct 08, 2007 12:18 pm    Post subject: Reply with quote

Огромное спасибо! Самый исчерпывающий ответ за последние 3 недели...
Писать я собираюсь на VC++. С ActiveX я просто еще не сталкивался(
С пунктами 2 и 3 все понятно. По пункту №1 у меня вопрос:
создание ActiveX контейнера с ... - это мне необхожимо создавать MFC ActiveX control или dll?
И если у меня в dllке имеется 3 метода, а мне для работы необходимы только 2? Всеравно создавать интерфреймы под все 3?
Back to top
View user's profile Send private message
admin
Администратор
Администратор



Joined: 01 Sep 2007
Posts: 1640

PostPosted: Mon Oct 08, 2007 1:38 pm    Post subject: Reply with quote

rudeman wrote:
По пункту №1 у меня вопрос:
создание ActiveX контейнера с ... - это мне необхожимо создавать MFC ActiveX control или dll?
И если у меня в dllке имеется 3 метода, а мне для работы необходимы только 2? Всеравно создавать интерфреймы под все 3?


Создавать нужно MFC ActiveX control. У меня дома лежит старая книжка "Visual C++ за 21 день" 98 года, там есть очень понятный пример по созданию ActiveX. Постараюсь найти дискету с примером. Или поишите в Интернет.

Нужно создать 2 интерфейсных метода. Это же обертка, которую вы сами пишете. Что хотите, то и отдавайте наружу. Можете добавить свои интерфейсные методы.
Back to top
View user's profile Send private message
rudeman
Специалист
Специалист



Joined: 21 Sep 2007
Posts: 55
Location: Киев

PostPosted: Mon Oct 08, 2007 2:00 pm    Post subject: Reply with quote

Спасибо большое. Буду пробовать.
Back to top
View user's profile Send private message
admin
Администратор
Администратор



Joined: 01 Sep 2007
Posts: 1640

PostPosted: Mon Oct 08, 2007 10:01 pm    Post subject: Reply with quote

С названием книги немного наврал.
С. Холзнер "Visual C++ учебный курс". 14 уроков для освоения языка. Издательсво Питер. 1999 год.
Нужная Вам глава здесь
http://www.sapnet.ru/viewtopic.php?p=507#507
Это пример для 5 версии, но картинки соотвествуют также и 6 версии Visual Studio. Насколько помню, в 7 поменялись пункты меню, но принципиально ничего не изменилось, этот код рабочий и для старших версии.
Back to top
View user's profile Send private message
rudeman
Специалист
Специалист



Joined: 21 Sep 2007
Posts: 55
Location: Киев

PostPosted: Wed Oct 10, 2007 11:11 am    Post subject: Reply with quote

Сделаю корпоративную рассылку со ссылкой на Ваш форум )
Огромное спасибо!
Back to top
View user's profile Send private message
rudeman
Специалист
Специалист



Joined: 21 Sep 2007
Posts: 55
Location: Киев

PostPosted: Wed Nov 21, 2007 2:14 pm    Post subject: Reply with quote

Т.е. механизм таков, что R/3 из таблицы TOLE по CLSID находит *.ocx, подгружает его, тот в свою очередь делает loadlibrary и выполняет функции библиотеки?
И второй вопрос... передаваемые параметры должны совпадать? Те что в R/3 и те что в базовой библиотеке?
Back to top
View user's profile Send private message
Lord
Профессионал
Профессионал



Joined: 10 Sep 2007
Posts: 168

PostPosted: Wed Nov 21, 2007 5:25 pm    Post subject: Reply with quote

1) Да.
2) Видимо возможны исключения, в общем случае на примере вызова методов excel
CALL METHOD OF H_EXCEL 'Cells' = H_ZL EXPORTING #1 = I #2 = J.
порядковый номер и тип параметра должны совпадать.
Back to top
View user's profile Send private message
rudeman
Специалист
Специалист



Joined: 21 Sep 2007
Posts: 55
Location: Киев

PostPosted: Mon Nov 26, 2007 6:12 pm    Post subject: Reply with quote

Quote:

report zsv02.
TYPE-POOLS OLE2.
DATA OleLib TYPE OLE2_object.
CREATE OBJECT OleLib 'CreateCred'.
write:/ sy-subrc.
CALL METHOD of Olelib 'InitCredA'
EXPORTING
#1 = 'I00001'
#2 = '7'
#3 = 'Welcome'
#4 = '0'
#5 = 'INFINITE'
#6 = '0'.
write:/ sy-subrc.

CreateCred - имя, под которым сделана запись в TOLE
Попробовал такое...
В результате при создании объекта sy-subrc=0, т.е. объект создан, а при вызове метода sy-subrc = 2, т.е. метод не вызывается.
В оригинале в оболочеке
Quote:

int iCode=(*pfnMyFunction1)("", &id_len, "", 0, "INFINITE",0)

т.е. чар, инт, чар, инт, чар, инт... порядок вроде соблюден, а вызова всеравно не наблюдается... ((
Back to top
View user's profile Send private message
vga
Мастер
Мастер


Age: 180
Joined: 04 Oct 2007
Posts: 1218
Location: Санкт-Петербург

PostPosted: Mon Nov 26, 2007 6:36 pm    Post subject: Reply with quote

Вы для начала создайте test метод без параметров.
В его реализации сделайте запись в локальный файл, чтобы знать, что он вызвался. Если все нормально, добавляетй по одному параметру, пока не найдете, на чем валится. От простого к сложному - правильный метод нахождения ошибок Laughing
Back to top
View user's profile Send private message Blog Visit poster's website
rudeman
Специалист
Специалист



Joined: 21 Sep 2007
Posts: 55
Location: Киев

PostPosted: Mon Nov 26, 2007 6:57 pm    Post subject: Reply with quote

Сделал метод просто с MessageBox... вааааапще нет вызова метода (
Или из под R/3 оно не вызовет messagebox?
Back to top
View user's profile Send private message
vga
Мастер
Мастер


Age: 180
Joined: 04 Oct 2007
Posts: 1218
Location: Санкт-Петербург

PostPosted: Mon Nov 26, 2007 9:08 pm    Post subject: Reply with quote

Вообще должен, но лучше в файл
Code:

FILE * fid = fopen("c:\Temp\_sap_test.txt","a");
fprintf(fid, "Method called\n");
fclose(fid);
Back to top
View user's profile Send private message Blog Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Russian ABAP Developer's Club Forum Index -> ABAP All times are GMT + 4 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


All product names are trademarks of their respective companies. SAPNET.RU websites are in no way affiliated with SAP AG.
SAP, SAP R/3, R/3 software, mySAP, ABAP, BAPI, xApps, SAP NetWeaver and any other are registered trademarks of SAP AG.
Every effort is made to ensure content integrity. Use information on this site at your own risk.