我如何优雅地将大量方法指针传递给用C编写的DLL?

时间:2014-01-10 23:18:28

标签: c delphi pointers dll

我有一个Delphi-Firemonkey应用程序,它通过用C编写的基于DLL的库管理其部分网络通信。由于目的是网络管理,库提供方法并且还需要来自相关应用程序的方法。 DLL只有一个主类。该类的编写方式使其在创建对象后立即开始工作,即没有像active或enabled等控制变量。

由于两种语言之间不兼容,因此只能访问简单方法。所以我将他们的指针传递给DLL中类的构造函数。

现在,我必须解决更多这样的方法,这些方法必须可以在DLL中调用。请引导我找到合适的解决方案。

1 个答案:

答案 0 :(得分:2)

  

我有一个C DLL,它进一步解决了多个C ++ DLL。

C DLL与C ++ DLL交互的事实完全无关紧要。您真正的问题只与您的Delphi代码和C DLL之间的交互有关。把它留在那。

  

为了使DLL能够从delphi应用程序调用方法,我将它们作为指向C DLL的指针传递。

C(或C ++)就无法调用Delphi对象实例方法。您只能使用非实例函数/过程。在这方面,是的,你必须将它们作为指针(并确保你在C中正确地声明它们以匹配它们在Delphi中的声明,包括调用约定,这非常重要)。

  

现在我必须添加20多个这样的方法。为了不损害可读性,我认为传递方法指针列表的指针应该是一个好主意。我之前从未制作过方法指针列表。

     

DLL对象在创建后立即开始处理,因此我需要将指针传递给它们的构造函数。

您可以让Delphi代码传递指向包含函数指针的record(C中的struct)的指针。如果需要,您可以在将来添加更多指向该记录的指针。 DLL可以复制record / struct中的函数指针,并将它们存储在对象可以找到它们的位置。

例如:

的Delphi:

type
  TGetValueFuncType = function: Integer; cdecl;
  ...
  TDllFuncPtrs = record
    GetValueFunc: TGetValueFuncType;
  end;

procedure DllSetFuncPtrs(var FuncPtrs: TGetValueFuncType); stdcall; external 'C.dll' name 'SetFuncPtrs';

...

function GetValue: Integer; cdecl;
begin
  Result := 12345;
end;

...

var
  FuncPtrs: TDllFuncPtrs;
begin
  FuncPtrs.GetValueFunc := @GetValue;
  ...
  DllSetFuncPtrs(FuncPtrs);
end;

C:

struct TDllFuncPtrs
{
    int __cdecl (*GetValueFunc)(void);
    ...
};

TDllFuncPtrs gFuncPtrs = {0};

__declspec(dllexport)
void __stdcall SetFuncPtrs(TDllFuncPtrs *FuncPtrs)
{
    gFuncPtrs = *FuncPtrs;
}

...

void DoSomething()
{
    int Value = 0;
    if (gFuncPtrs.GetValueFunc != NULL)
        Value = gFuncPtrs.GetValueFunc();
    ...
}