我有一个Delphi-Firemonkey应用程序,它通过用C编写的基于DLL的库管理其部分网络通信。由于目的是网络管理,库提供方法并且还需要来自相关应用程序的方法。 DLL只有一个主类。该类的编写方式使其在创建对象后立即开始工作,即没有像active或enabled等控制变量。
由于两种语言之间不兼容,因此只能访问简单方法。所以我将他们的指针传递给DLL中类的构造函数。
现在,我必须解决更多这样的方法,这些方法必须可以在DLL中调用。请引导我找到合适的解决方案。
答案 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();
...
}