Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.09.25;
Скачать: CL | DM;

Вниз

Возврат интерфейса в Builder   Найти похожие ветки 

 
DmitriyG. ©   (2011-05-23 23:45) [0]

Есть интерфейс (Delphi):

 IPainter = interface
   ["{1A4E467E-2C22-47FD-92B9-7107E4A58DED}"]
   procedure Draw; stdcall;
 end;


И простейший класс TPainter, который реализует этот интерфейс:

 TPainter = class(TInterfacedObject, IPainter)
 private
   Image : TImage;
 public
   constructor Create(const Image : TImage);
   destructor Destroy; override;

   procedure Draw; stdcall;
 end;


Создал библиотеку, которая экспортирует фнукцию

function GetPainter(const Image : TImage) : IPainter; stdcall;
begin
 Result := TPainter.Create(Image);
end;
.....
exports
GetPainter;
....


Теперь пытаюсь из C++ Builder получить указатель на интерфейс и использовать его....
Для простоты подключаю pas файл с описанием интерфейса IPainter. Генерится hpp файл с описанием интерфейса.
Затем подключаю lib и описываю прототип:

extern "C" IPainter * __stdcall __declspec(dllimport) GetPainter(void *image);



//Получаю указатель на интерфейс
IPainter* painter = GetPainter(Image1);
//пытаюсь вызвать функцию (но вылетает AV)
painter->Draw();


Если же библиотеку подключать в Delphi то проблем нет....
Что я не так делаю в случае использования Builder"a?


 
sniknik ©   (2011-05-24 00:20) [1]

TImage ??? дельфийский класс? vcl? никогда подобного не делал, но "что то не ладно в Датском королевстве".
не пробовал вместо него чего нибудь "классическое", т.е. системное передавать?


 
Inovet ©   (2011-05-24 00:45) [2]

> [0] DmitriyG. ©   (23.05.11 23:45)
> function GetPainter(const Image : TImage) : IPainter; stdcall;

> extern "C" IPainter * __stdcall __declspec(dllimport) GetPainter(void *image);

А, кстати, почему void*, а не TImage*?


 
sniknik ©   (2011-05-24 07:52) [3]

> А, кстати, почему void*, а не TImage*?
это то как раз понятно... откуда в C++ TImage? чтобы объявить его типом.


 
icWasya ©   (2011-05-24 09:57) [4]

>откуда в C++ TImage?
В Билдере как раз есть.
НО.
В данном случае требуется использование ShareMem и одинаковость версий Delphi и Builder.


 
Dimka Maslov ©   (2011-05-24 10:57) [5]

Не рекомендуется возвращать функцией указатель на интерфейс, а передавать как void** IfacePtr в Сях или out IfacePtr в Delphi


 
Inovet ©   (2011-05-24 12:03) [6]

> [4] icWasya ©   (24.05.11 09:57)
> ShareMem и одинаковость версий Delphi и Builder

1, ShareMem, ты же указатель передаёшь, а диспетчер памяти или общий или разный, смотря как надо
2. Одинаковость версий, так ты ведь всё равно с ним потом работаешь, как c TImage.


 
DmitriyG. ©   (2011-05-24 15:31) [7]

Можно и TImage * вместо void * передавать...
Версии Delphi и Builder одинаковые....
Т.е. думаете дело в ShareMem?
Через двойной указатель пробовал - то же самое
void** IfacePtr в Сях или out IfacePtr в Delphi
только я пробовал (var painter : IPainter)


 
DmitriyG. ©   (2011-06-03 00:00) [8]

Все получилось действительно оказалось, что нужно возвращать интерфейс через модификатор out:
procedure GetPainter(out Painter : IPainter); stdcall;
ну а дальше в Си использовать двойной указатель на него...



Страницы: 1 вся ветка

Текущий архив: 2011.09.25;
Скачать: CL | DM;

Наверх




Память: 0.48 MB
Время: 0.005 c
2-1307186837
FIL-23
2011-06-04 15:27
2011.09.25
Есть ли функция "примерно"


2-1307578301
Сергей
2011-06-09 04:11
2011.09.25
Отправка из php в Delphi функцией echo в массив строк


15-1307162500
boriskb
2011-06-04 08:41
2011.09.25
Не смог не поделиться


2-1307195961
Buzzik
2011-06-04 17:59
2011.09.25
Treeview, как хранить?


15-1306787399
Юрий
2011-05-31 00:29
2011.09.25
С днем рождения ! 31 мая 2011 вторник