Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - [решено] Как в С вызвать функцию из Delphi библиотеки?

Ответить
Настройки темы
C/C++ - [решено] Как в С вызвать функцию из Delphi библиотеки?

Новый участник


Сообщения: 5
Благодарности: 1

Профиль | Отправить PM | Цитировать


В заголовочном файле (header.pas)
определен интерфейс

Код: Выделить весь код
 ControlInterface = interface
   function f_check: Boolean; stdcall;
   function f_user(dwType: DWORD; Proc: Pointer; User: DWORD): Boolean; stdcall;
   function f_rem(dwType: DWORD; Proc: Pointer): Boolean; stdcall;
 end;
Как вызвать эти функции (f_check, f_user, f_rem) из модуля написанного на C?

Как вызвать из C++ Builder я знаю. Мне же нужно вызывать из C без борланда, без плюсов.

Отправлено: 13:28, 01-07-2009

 

Аватара для Alan85

Старожил


Сообщения: 463
Благодарности: 91

Профиль | Отправить PM | Цитировать


Т.е. Вы хотите чтобы Си "понял" Delphi на уровне исходников? или все же есть dll. C++ Builder имеет компилятор Delphi и большинство его компонентов и модулей именно на делфях сделаны поэтому понимает исходники а вот чистый си не сможет.

Отправлено: 19:26, 01-07-2009 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля.

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


на с++ будет выглядеть так:
Код: Выделить весь код
typedef unsigned long DWORD;

class ControlInterface
{
public:
  virtual bool __stdcall f_check() = 0;
  virtual bool __stdcall f_user(DWORD dwType, void* proc, DWORD User) = 0;
  virtual bool __stdcall f_rem(DWORD dwType, void* proc) = 0;
};
если коспилятор не поддерживает виртуальные функции:
Код: Выделить весь код
typedef unsigned long DWORD;
typedef bool __stdcall (*f_check_t)();
typedef bool __stdcall (*f_user_t)(DWORD dwType, void* proc, DWORD User);
typedef bool __stdcall (*f_rem_t)(DWORD dwType, void* proc);

struct ControlInterface
{
  f_check_t f_check;
  f_user_t   f_user;
  f_rem_t    f_rem;
};

// вызов:
ControlInterface* interface = GetInterface(...);
interface->f_check();
Это сообщение посчитали полезным следующие участники:

Отправлено: 06:52, 02-07-2009 | #3


Новый участник


Сообщения: 5
Благодарности: 1

Профиль | Отправить PM | Цитировать


Alan85,
есть dll и заголовочный файл для неё.
И C++ Builder правильно понимает это все.
Делает что-то типа
Код: Выделить весь код
__interface ControlInterface;
typedef System::DelphiInterface<ControlInterface> _di_ControlInterface;
__interface ControlInterface  : public IInterface {
...
};
Мне же нужно вызывать функции dll из MinGW C. Ну, не "нужно" я так хочу просто.


pva, спасибо.
Кажись это работает - в структуру я попадаю, но кажись промахиваюсь мимо функций, т.к. результат немного неожиданный.
Сейчас поэкспериментирую.

И еще, я немного (я думаю, что немного) изменил объявление структуры
Код: Выделить весь код
typedef struct ControlInterface
{
   bool __stdcall (*f_check)(void);
   bool __stdcall (*f_user)(DWORD dwType, void* proc, DWORD User);
   bool __stdcall (*f_rem)(DWORD dwType, void* proc);
} *pControlInterface;

// вызов:
pControlInterface interface = GetInterface(...);
interface->f_check();
Вроде то же самое. По крайней мере адреса функций такие же как в Вашем варианте получаются.

Отправлено: 14:32, 02-07-2009 | #4

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


Код: Выделить весь код
__interface ControlInterface;
typedef System::DelphiInterface<ControlInterface> _di_ControlInterface;
__interface ControlInterface  : public IInterface {
...
};
скорее всего это класс ActiveX, у него должна быть ещё куча функций (поэтому и результат неожиданный). Покажи точное описание интерфейса (хотя бы на паскале)

Отправлено: 07:28, 03-07-2009 | #5


Новый участник


Сообщения: 5
Благодарности: 1

Профиль | Отправить PM | Цитировать


Наэкспериментировал.
Первые три указателя в структуре указывают на какие-то "системные" функции. Эти "системные" функции имеют вид
@System@@IntfAddRef$qqrx45System@%DelphiInterface$t17System@IInterface%

Каждой функции в структуре передаётся первым параметром еще и указатель на указатель на структуру (в терминах C++ это this)
"указатель на указатель" не опечатка - если в паскале объявлен объект
Код: Выделить весь код
var
      o: ControlInterface;
то в С это будет
Код: Выделить весь код
ControlInterface **o;
В результате структура выглядит так:
Код: Выделить весь код
typedef struct ControlInterface
{
   void __stdcall (*fake1)(void *);
   void __stdcall (*fake2)(void *);
   void __stdcall (*fake3)(void *);
   bool __stdcall (*f_check)(void *This);
   bool __stdcall (*f_user)(void *This, DWORD dwType, void* proc, DWORD User);
   bool __stdcall (*f_rem)(void *This, DWORD dwType, void* proc);
} *pControlInterface;

// И вызов:
pControlInterface *interface = GetInterface(...);
(*interface)->f_check(interface);
(*interface)->f_check(interface, dwType, proc, User);
Как то "корявенько" получилось :-).

pva, точное описание интерфейса по этому адресу. Это SDK для аудио плейера AIMP.

Отправлено: 02:31, 04-07-2009 | #6

pva pva вне форума

Аватара для pva

Ветеран


Сообщения: 1180
Благодарности: 279

Профиль | Отправить PM | Цитировать


AddRef, Release и QueryInterface - это члены класса IUnknown. Советую почитать про технологию COM - тогда станет понятней. Если не вызывать Release, то возможны проблемы с памятью, поэтому рекомендую сделать так:
Код: Выделить весь код
typedef struct ControlInterface
{
        HRESULT ( STDMETHODCALLTYPE *QueryInterface )( 
            IUnknown * This,
            /* [in] */ REFIID riid,
            /* [iid_is][out] */ void **ppvObject);

        
        ULONG ( STDMETHODCALLTYPE *AddRef )( 
            IUnknown * This);
        
        ULONG ( STDMETHODCALLTYPE *Release )( 
            IUnknown * This);
        
   bool __stdcall (*f_check)(void *This);
   bool __stdcall (*f_user)(void *This, DWORD dwType, void* proc, DWORD User);
   bool __stdcall (*f_rem)(void *This, DWORD dwType, void* proc);
} *pControlInterface;

...

// попользовались
 interface->Release(my_class);
но если компилятор всё-же поддерживает виртуальные функции, то лучше не париться и сделать по-человечески:
Код: Выделить весь код
struct ControlInterface : IUnknown
{
   bool __stdcall f_check();
   bool __stdcall (DWORD dwType, void* proc, DWORD User);
   bool __stdcall (DWORD dwType, void* proc);
} *pControlInterface;

...

// попользовались
 interface->Release();

Отправлено: 10:11, 06-07-2009 | #7



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - [решено] Как в С вызвать функцию из Delphi библиотеки?

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
VBS/WSH/JS - [решено] Как вызвать диалоговое окно открытия файла? jaki Скриптовые языки администрирования Windows 4 30-03-2011 12:12
Разное - как вызвать функцию hhh8486 Программирование и базы данных 2 29-03-2008 13:17
как автоматом вызвать активацию ? djoniAg Автоматическая установка Windows 2000/XP/2003 1 19-12-2004 01:23
как вызвать скрипт на страницу? koresaram Программирование и базы данных 5 08-07-2003 18:21
как вызвать командную строку modem Общий по Linux 8 06-07-2003 07:11




 
Переход