Конференция "Corba" » Внешний COM сервер не хочет отдавай строку [Delphi, Windows]
 
  • intenser © (09.11.10 16:07) [0]
    Пишу внешний COM сервер с единственным COM объектом, имеющим одну функцию, которая возвращает текст WideString:

    function GetText: WideString; stdcall;

    На стороне клиента подключаюсь к существующему COM-объекту (при помощи GetActiveOleObject) и пытаюсь вызывать эту функцию. Вызов падает с ошибками "Catastropthic failure", "The server threw an exception" или "Access Violation" (я менял stdcall на safecall, WideString на POleStr, в различных комбинациях разные ошибки).

    При этом, если использовать функцию, возвращающему число,а не текст,то она корректно работает. Также корректно работает,если не подключаться к существующему объекту, а создавать его при помощи CreateOleObject.

    Понимаю, что ошибка где-то в области маршалинга и доступа к чужому адресному пространству, но не знаю, как решить проблему. Кто-нибудь сталкивался?
  • clickmaker © (09.11.10 17:12) [1]
    версия Дельфи?
    какая потоковая модель у сервера?
    клиент тоже на Delphi?
  • intenser © (09.11.10 18:03) [2]
    Версия Дельфи - 2010. Но проверял в 7-й - тот же эффект.

    Потоковая модель tmApartment

    Клиент тоже на Delphi.
  • clickmaker © (10.11.10 12:06) [3]
    вот в таком случае какая именно ошибка вылезает?
    function GetText: WideString; safecall;

    а в таком?
    function GetText: OleVariant; safecall;
  • intenser © (10.11.10 12:48) [4]
    В обеих случаях "The server threw an exception"
  • clickmaker © (10.11.10 12:59) [5]
    хм... а текст самой функции в части заполнения результирующей строки как выглядит?
  • intenser © (10.11.10 13:03) [6]
    Вот так:

    begin
     result := 'Hello world!';
    end;



    Но я пробовал кучу различных вариантов - и передавать в виде PWideChar, и значение переменной, и даже всякие комбинации с функцией StringToLPOLESTR... Ничего не помогает.

    У меня есть маленький (простейший) тест-кейс. Его здесь можно как-то выложить?
  • clickmaker © (10.11.10 13:19) [7]
    > Его здесь можно как-то выложить?

    здесь нет. можно на любой файлообменник, а здесь - сцылку
  • intenser © (10.11.10 13:28) [8]
  • clickmaker © (10.11.10 13:46) [9]
    а почему в библиотеке типов этого метода нет?
    нужно добавить. View - Type library - add method - возр. значение HRESULT и один параметр out retval типа BSTR*
    будет
    // *********************************************************************//
    // Interface: ISharedMemoryNameClass
    // Flags:     (4416) Dual OleAutomation Dispatchable
    // GUID:      {65C0FB26-7C9A-4F26-827A-F1F9BCF15D16}
    // *********************************************************************//
     ISharedMemoryNameClass = interface(IDispatch)
       ['{65C0FB26-7C9A-4F26-827A-F1F9BCF15D16}']
       function GetSharedMemoryName: WideString; stdcall;
       procedure Method1; safecall;
       function Method2: PWideChar; stdcall;
       function GetText: WideString; safecall;
     end;

    // *********************************************************************//
    // DispIntf:  ISharedMemoryNameClassDisp
    // Flags:     (4416) Dual OleAutomation Dispatchable
    // GUID:      {65C0FB26-7C9A-4F26-827A-F1F9BCF15D16}
    // *********************************************************************//
     ISharedMemoryNameClassDisp = dispinterface
       ['{65C0FB26-7C9A-4F26-827A-F1F9BCF15D16}']
       function GetSharedMemoryName: WideString; dispid 201;
       procedure Method1; dispid 202;
       function Method2: {??PWideChar}OleVariant; dispid 203;
       function GetText: WideString; dispid 204;
     end;
  • intenser © (10.11.10 13:59) [10]
    Упс, это издержки подготовки тест-кейса...

    Сейчас убрал всё, оставил одну функцию:
    // *********************************************************************//
    // Interface: ISharedMemoryNameClass
    // Flags:     (4416) Dual OleAutomation Dispatchable
    // GUID:      {65C0FB26-7C9A-4F26-827A-F1F9BCF15D16}
    // *********************************************************************//
     ISharedMemoryNameClass = interface(IDispatch)
       ['{65C0FB26-7C9A-4F26-827A-F1F9BCF15D16}']
       function GetText: WideString; safecall;
     end;

    // *********************************************************************//
    // DispIntf:  ISharedMemoryNameClassDisp
    // Flags:     (4416) Dual OleAutomation Dispatchable
    // GUID:      {65C0FB26-7C9A-4F26-827A-F1F9BCF15D16}
    // *********************************************************************//
     ISharedMemoryNameClassDisp = dispinterface
       ['{65C0FB26-7C9A-4F26-827A-F1F9BCF15D16}']
       function GetText: WideString; dispid 201;
     end;



    ... которую добавил именно так:
    View - Type library - add method - возр. значение HRESULT и один параметр out retval типа BSTR*

    Но это всё равно не помогло мне. А у Вас работает?
  • clickmaker © (10.11.10 14:04) [11]
    > А у Вас работает?

    да
  • intenser © (10.11.10 14:10) [12]
    Оооо..... У меня заработало тоже!!!

    Спасибо огромное! :-)
 
Конференция "Corba" » Внешний COM сервер не хочет отдавай строку [Delphi, Windows]
Есть новые Нет новых   [118462   +18][b:0.002][p:0.002]