我有一个用Delphi编写的库L,它使用方法M.程序P使用库L的方法M.
L看起来有点像这样:
library L;
// uses and stuff ...
function M(i: Integer; k: Integer): Integer stdcall;
begin
Result := i*k;
end;
exports
M;
begin
end.
P看起来有点像这样:
// uses and begin and class and stuff ...
type
TTheMethod = function(i: Integer; k: Ineteger): Integer stdcall;
var
hLib: THandle;
methodVar: TTheMethod;
a: Iteger;
begin
hLib := LoadLibrary(PWideChar('someFile.dll'));
methodVar:= GetProcAddress(hLib, 'M');
a := methodVar(2, 21);
如果我改变我的库以便M期望3个整数,那么程序P仍然会编译。 Delphi并不知道M和methodVar需要具有相同的类型。如果M和methodVar中只有一个更改了类型,我希望我的编译器失败。
我尝试将库更改为:
function _M(i: Integer; k: Integer): Integer stdcall;
begin
Result := i*k;
end;
var
M: TTheMethodA = _M;
exports
M;
但那不会编译。
我可以以某种方式让编译器为我检查类型吗?
答案 0 :(得分:2)
我可以以某种方式让编译器为我检查类型吗?
不,你不能。编译器根本无法验证外部函数的签名。实际上,从DLL导出的函数不包含任何元数据来标识其签名。
你得到的最接近的是C ++名称修改,它在其装饰名称中编码函数的签名。但是,这对你没有用,因为Delphi没有任何名称修改功能。
至于您的代码,您无法导出过程类型的变量。您必须导出实际功能。您可以像这样编写最后一段代码:
divInput.onkeypress = function (event){
return someTestFunc();
}
divInput.tabIndex="-1";
$(divInput).focusout(function (e) {
if ($(this).find(e.relatedTarget).length == 0) {
addToList();
}
});
或者,如果您希望通过变量进行路由的灵活性,那么您将以类似的方式进行:
function _M(i: Integer; k: Integer): Integer stdcall;
begin
Result := i*k;
end;
function M(i: Integer; k: Integer): Integer stdcall;
begin
Result := _M(i, k);
end;
exports
M;
答案 1 :(得分:0)
没有办法做到这一点。 GetProcAddress
只提供了一个指向过程条目的指针,而没有任何附加信息应该如何调用它,它需要多少个参数,如何以及在哪个顺序传递参数。即使是C ++名称错误,也无法帮助你,因为毕竟 - 它只是一个错误的名称,没有什么能阻止你向方法传递错误的参数计数(毕竟它的简单指针)。使用它可以达到的最大值 - ....
$http({
url: aAPIname,
method: "POST",
data: req,
responseType: "arraybuffer",
headers: oHeaders,
})
.success(function(data, status) {
deff.resolve(data);
})
....
将无法找到更改的过程,因为它的名称会有所不同。但它仍然是运行时检查而不是编译时验证。