我需要你的帮助。我正试图从Inno Setup(ANSI)的Delphi 10 Seattle中编写的DLL中调用函数。但我不明白这是什么问题。如果我在Delphi中创建应用程序并从DLL调用此函数,它的工作完美!请参阅代码清单:
Delphi DLL:
import Foundation
import UIKit
class TestView: UIViewController, UITextInputTraits {
@IBOutlet weak var TestLabel: UILabel!
@IBOutlet weak var TypingField: UITextField!
@IBOutlet weak var progressView: UIProgressView!
var time : Float = 0.0
var timer: NSTimer!
var test = 0;
var progress : Float = 1
var myMutableString = NSMutableAttributedString()
var testStringArray = ["abode" , "tutorial" , "completed",
"war", "method", "continue",
"machine", "texting" , "iterate"]
var idx = 0;
var setProg : Float = 1
func textFieldDidChange(textField: UITextField) {
let s = TypingField.text!
if(s.characters.last == " "){
let word = s.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceCharacterSet())
if(!word.isEmpty){
print(testStringArray[idx])
if(word == testStringArray[idx]){
idx++;
TypingField.text = "";
TestLabel.text = testStringArray[idx];
}else{
TypingField.text = "";
}
}
}
}
func setProgress() {
setProg -= 0.1
progressView.progress = setProg <-- cannot decrement progress bar
}
override func viewDidLoad() {
super.viewDidLoad()
TypingField.autocorrectionType = .No
TypingField.autocapitalizationType = .None
timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector:Selector("setProgress"), userInfo: nil, repeats: true)
TestLabel.text = testStringArray[idx];
TypingField.addTarget(self, action: "textFieldDidChange:", forControlEvents: UIControlEvents.EditingChanged)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Inno Setup(ANSI):
function Process(Pb: TProgressBar): Integer; stdcall;
var
I: integer;
begin
for I := 0 to 1000 do
begin
Pb.Position := I;
Pb.Update;
Sleep(10);
end;
end;
Exports
Process;
通话结束后,我得到访问冲突。但是,在我阅读的dpr文件中注释, ShareMem 写第一行,但效果为零。
请告诉我如何从Delphi DLL正确更新Inno Setup中的进度条。
答案 0 :(得分:1)
您不能以这种方式调用对象方法。如果您使用完全相同版本的Delphi,您可能会很幸运,因为您使用Delphi应用程序的测试显示。但它仍然是错误和不可靠的,不要这样做。当您使用不同的Delphi版本时,内存中进度条类的布局是不同的,因此“访问冲突”。
对于此特定任务,您只需使用进度条的句柄即可轻松完成:
function Process(Handle: THandle): Integer;
var
I: Integer;
begin
SendMessage(Handle, PBM_SETRANGE, 0, 1000 shl 16);
for I := 0 to 1000 do
begin
SendMessage(Handle, PBM_SETPOS, I, 0);
UpdateWindow(Handle);
Sleep(10);
end;
end;
在Inno Setup中,调用如下函数:
function Count(Handle: THandle): integer; external 'Process@files:CallC.dll stdcall delayload';
procedure NewButton1Click(Sender: TObject);
begin
Count(NewProgressBar1.Handle);
end;
对于更高级的任务,您需要使用回调。
见