2013-05-15 3 views
0

Есть декларации в собственной DLL заголовка:Ответный в Free Pascal от C++ DLL

class CJDummyClass 
{ 
}; 
typedef CJDummyClass * J_IMG_CALLBACK_OBJECT; 
#ifdef __BORLANDC__ 
    typedef void (__stdcall*J_IMG_CALLBACK_FUNCTION)(J_tIMAGE_INFO * pAqImageInfo); 
#else 
    typedef void (CJDummyClass::*J_IMG_CALLBACK_FUNCTION)(J_tIMAGE_INFO * pAqImageInfo); 
#endif 

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

Я пишу приложение, использующее эту DLL в FreePascal, почти все, что мне нужно, успешно переведенное, динамически связанное и завернутое в класс, но теперь у меня проблема с функцией обратного вызова. Вот часть моего кода:

interface 
type 
    pJ_tIMAGE_INFO = ^J_tIMAGE_INFO; 
    TJ_IMG_CALLBACK_FUNCTION = procedure(const pAqImageInfo: pJ_tIMAGE_INFO) of object; cdecl; 
    PJ_IMG_CALLBACK_FUNCTION = ^TJ_IMG_CALLBACK_FUNCTION; 

    TJaiFactory = class(TObject) 
    ..... 
    procedure ImageCallback(const pAqImageInfo: pJ_tIMAGE_INFO); cdecl; 
    ..... 
    end; 
implementation 
procedure TJaiFactory.ImageCallback(pAqImageInfo: pJ_tIMAGE_INFO); cdecl; 
begin 
    // some data processing here 
end; 

Insidy моего ImageCallback я получил pAqImageInfo = ноль вместо некоторого фактического указателя. Я подозреваю, что мне нужно определить тип или параметры для обратного вызова каким-то другим способом, но я не знаю, как это сделать.

Первый вопрос: если в C++ существует функция void, то насколько я понимаю, это процедура в терминах Pascal, и она должна быть определена как процедура или как функция с некоторым результатом указателя (но без фактического результата)?

Второй вопрос: если функция, объявленная в C++ как член класса, является правильным способом перевести тип этой функции в Pascal? Я не уверен, что происходит с этим «указателем».

спасибо.

ответ

1
  1. процедура эквивалентна функции void в C/C++.
  2. В Visual C++, this указатель передается в ecx регистр, а вызов по умолчанию для функции-члена эквивалентен __stdcall, за исключением случаев, когда вы передали вариационный аргумент, он изменится на __cdecl. Ваш обратный вызов должен быть корректным, кроме соглашения о вызове.
+0

спасибо. Но я все еще не понимаю о вызове конвенции для функции-члена. Как объявить его в Паскале? Должен ли я заявить что-то или предоставить что-то, чтобы сделать обратный вызов правильным? Я не уверен, но похоже, что нуль в указателе равен нулю для «этого». Я тоже пробовал stdcall, и результат был таким же - ноль в указателе. –

+0

Является DLL x86? А что такое компилятор, который использует DLL? Является ли вызов конвенции для функции-члена в Free Pascal такой же, как Delphi? Я ничего не знаю о Free Pascal. Но в Delphi первый аргумент передается в регистре edx. – UltimaWeapon

+0

DLL - x86, компилятор Free Pascal - тоже x86, а в режиме delphi-совместимости (когда он был в режиме objfpc по умолчанию, функция обратного вызова вообще не была связана). –

0
  1. A * bla() эквивалентно bla(). IOW функция TYPE является неявным указателем в Pascal.
  2. Класс C++ не может быть представлен в другом компиляторе. Даже два компилятора C++ могут иметь разные представления.
  3. В результате (2) тип функции не имеет ОБЪЕКТА. Это не класс Паскаля. OBJECT сделает тип функции двух типов указателей (экземпляр + адрес), afaik - понятие, которое не имеет C++.

Так

Type 
    J_IMG_CALLBACK_FUNCTION = procedure (pAqImageInfo:Pointer); StdCall; 
// or cdecl depending on compiler 

является разумным приближением.

+0

Спасибо тоже! Оно работает! –

Смежные вопросы