Главная страница
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.012 c
2-1307185803
Blaber
2011-06-04 15:10
2011.09.25
Решить задачу линейного программирования


2-1307121220
Gu
2011-06-03 21:13
2011.09.25
Png модули


2-1307609717
@!!ex
2011-06-09 12:55
2011.09.25
Как установить Charset для всех шрифтов?


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


15-1303815269
OW
2011-04-26 14:54
2011.09.25
Построитель диаграмм готовых БД для Oracle. Ищу.