我有一软件,delphi做界面,vc dll做逻辑部分,但dll部分需要delphi做个界面支持好在中途输入参数,问题是输入参数时界面显示不出来。代码大致如下,大家帮忙看看怎么解决。
//delphi code
TFrom2 = class(TForm)
...
end;
TFrom1 = class(TForm)
...
end;function MyCallBack(buf:PAnsiChar):Boolean;
var
f2 : TForm2;
begin
f2 := TForm2.Create(nil);
f2.ShowModal();
f2.GetArgument(buf);
f2.Free();
f2 := nil;
Result := True;
end;procedure TForm1.Btn1Click(Sender:TObject);
begin
...
ret := dll_api_call(MyCallBack);
...
end;
//vc dll code
int result_code = 0;
DWORD dll_thread_fun(delphi_cb_fun){
....
delphi_cb_fun(buf);
....
ExitThread(0);
return 0;
}int dll_api_call(delphi_cb_fun){
...
HANDLE hThread = CreateThread(....dll_thread_fun,delphi_cb_fun);
while (result_code == 0){
Sleep(1000);
}
CloseHandle(hThread);
hThread = NULL;
return result_code;
}也就是delphi主界面上点击一按钮,将回调函数的指针传入调用dll一接口,接口内新开一子线程处理逻辑,中途利用回调函数获取参数,主线程等待结果后返回,新开的子线程需要一直运行,由另一接口负责释放,但问题是子线程内调用回调函数时,无法正常显示预期的TForm2窗体,在 f2 := TForm2.Create();这一行停止了,但程序未死,TForm2.OnCreate()函数可被执行。
//delphi code
TFrom2 = class(TForm)
...
end;
TFrom1 = class(TForm)
...
end;function MyCallBack(buf:PAnsiChar):Boolean;
var
f2 : TForm2;
begin
f2 := TForm2.Create(nil);
f2.ShowModal();
f2.GetArgument(buf);
f2.Free();
f2 := nil;
Result := True;
end;procedure TForm1.Btn1Click(Sender:TObject);
begin
...
ret := dll_api_call(MyCallBack);
...
end;
//vc dll code
int result_code = 0;
DWORD dll_thread_fun(delphi_cb_fun){
....
delphi_cb_fun(buf);
....
ExitThread(0);
return 0;
}int dll_api_call(delphi_cb_fun){
...
HANDLE hThread = CreateThread(....dll_thread_fun,delphi_cb_fun);
while (result_code == 0){
Sleep(1000);
}
CloseHandle(hThread);
hThread = NULL;
return result_code;
}也就是delphi主界面上点击一按钮,将回调函数的指针传入调用dll一接口,接口内新开一子线程处理逻辑,中途利用回调函数获取参数,主线程等待结果后返回,新开的子线程需要一直运行,由另一接口负责释放,但问题是子线程内调用回调函数时,无法正常显示预期的TForm2窗体,在 f2 := TForm2.Create();这一行停止了,但程序未死,TForm2.OnCreate()函数可被执行。
class ID2C {
public:
virtual int respone(int i) = 0;
};//Delphi调用C++接口,由C++实例化
class IC2D {
public:
virtual int max(int a, int b) = 0;
virtual void SetID2C(ID2C *d2c) = 0; //将Delphi实例化的指针传入
};//C++实例化
class CC2D {
public:
virtual void SetID2C(ID2C *d2c) {
m_d2c = d2c;
}
virtual int max(int a, int b) {
//这里调用delphi的代码
if (m_d2c != NULL) {
m_d2c->respone();
}
if (a >= b) return a;
else return b;
}
private:
ID2C *m_d2c;
};//导出dll实例的指针
library Test
Exports CreateIC2D;IC2D* CreateIC2D() {
IC2D *c2d = new CC2D;
return c2d;
}
type
//C++调用Delphi接口,由Delphi实例化
ID2C = class
public
function respone(i: integer): integer;virtual;stdcall;abstract;
end;//Delphi实例化
TD2C = class(ID2C)
public
function respone(i: integer): integer;override;
end;//Delphi调用C++接口,由C++实例化
IC2D = class
public:
function max(a, b: integer): integer;virtual;stdcall;abstract;
procedure SetID2C(d2c: ID2C);virtual;stdcall;abstract;
end;//Delphi响应C++的处理
function TD2C.respone(i: integer): integer;
begin
result: = i*2;
end;//在Delphi里调用过程------------------------
var
c2d: IC2D;
d2c: ID2C;
begin
//调用dll暴露出的C++得到接口
c2d: = CreateIC2D;
//delphi实例化接口,并将指针传给c2d
d2c:=TD2C.create();
c2d.SetID2C(d2c); //那么此时,调用max的过程中,回调了respone,而这段代码是由delphi写的,作为对底层的响应
c2d.max(2, 3);
end;
我想你应该用function MyCallBack(buf:PAnsiChar):Boolean; stdcall;吧。
然后不要在CreateThread中来调用展现界面的方法,这样会出错,展现界面要在主线程中进行调用。
所以建议你把MyCallBack封装成线程安全的,也就是直接在里面SendMessage,然后在消息映射的方法中展现窗体。