【问题标题】:Callback in Free Pascal from C++ DLL来自 C++ DLL 的 Free Pascal 回调
【发布时间】:2013-05-15 10:38:49
【问题描述】:

专有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处理一些放在内存中的数据

我在 FreePascal 中使用这个 DLL 编写应用程序,几乎所有我需要的东西都成功翻译、动态链接并包装到一个类中,但现在我遇到了回调函数的问题。 这是我的代码的一部分:

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 = nil 而不是一些实际的指针。我怀疑我必须以其他方式为回调定义类型或参数,但我不知道如何。

第一个问题:如果在 C++ 中有一个 void 函数,那么据我所知,它是 Pascal 方面的过程,它应该被定义为过程或带有一些指针结果的函数(但没有实际结果)?

第二个问题:如果函数在 C++ 中声明为类的成员,那么将这个函数的类型转换为 Pascal 的正确方法是什么?我不确定“this”指针发生了什么。

谢谢。

【问题讨论】:

    标签: c++ dll callback freepascal


    【解决方案1】:
    1. 过程相当于 C/C++ 中的 void 函数。
    2. 在 Visual C++ 中,this 指针在 ecx 寄存器中传递,成员函数的默认调用约定等同于 __stdcall,除非您传递可变参数时,它会更改为 __cdecl。除了调用约定之外,您的回调应该是正确的。

    【讨论】:

    • 谢谢。但是我仍然不了解成员函数的调用约定。我应该如何在 Pascal 中声明它?我应该声明一些东西还是提供一些东西来使回调正确?我不确定,但看起来指针中的 nil 对于“this”来说是 nil。我也试过stdcall,结果是一样的——指针为零。
    • DLL 是 x86 吗? DLL 使用的编译器是什么? Free Pascal 中成员函数的调用约定是否与 Delphi 相同?我对 Free Pascal 知之甚少。但是,在 Delphi 中,第一个参数是在 edx 寄存器中传递的。
    • DLL 是 x86,Free Pascal 编译器也是 x86,并且在 delphi 兼容模式下(当它处于默认 objfpc 模式时,回调函数根本没有链接)。
    • 检查您的专有 DLL 它使用的是什么编译器。如果是 Visual C++,procedure ImageCallback(pAqImageInfo: pJ_tIMAGE_INFO); stdcall; 应该可以工作。不要将ImageCallback 作为成员函数。如果你这样做,Free Pascal 会将pAqImageInfo 分配给edx 寄存器,而不是VC++ 在堆栈中传递的变量。
    • 非常感谢!我确定我检查了这个组合,但是......现在我没有检查。或者是当我使用 objfpc 模式而不是与 delphi 兼容的时候。无论如何,谢谢!
    【解决方案2】:
    1. *bla() 等效于 bla()。 IOW 函数 TYPE 隐含地是 Pascal 中的指针。
    2. 不能在不同的编译器中表示 C++ 类。即使是两个 C++ 编译器也可能有不同的表示。
    3. 由于 (2),函数类型不是 OF OBJECT。它不是 Pascal 类。 OF OBJECT 将使函数类型成为两个指针类型(实例 + 地址),这是 C++ 没有的概念。

    所以

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

    是一个合理的近似值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-03-13
      • 1970-01-01
      • 2011-05-03
      • 1970-01-01
      • 1970-01-01
      • 2016-01-18
      • 1970-01-01
      相关资源
      最近更新 更多