線上訂房服務-台灣趴趴狗聯合訂房中心
發文 回覆 瀏覽次數:1806
推到 Plurk!
推到 Facebook!

呼叫dll執行,執行時間過長導致畫面變白

答題得分者是:boss.tw
maplefog
一般會員


發表:16
回覆:24
積分:13
註冊:2008-11-08

發送簡訊給我
#1 引用回覆 回覆 發表時間:2010-04-17 15:03:40 IP:140.118.xxx.xxx 訂閱

各位好:

我程式中呼叫dll檔,如下所示

[code cpp]
int (*maxdg)(double *,const int,const int,char *,double,double,double,int,double);
HINSTANCE hInst = LoadLibrary(pathx.c_str());
(FARPROC &)maxdg = GetProcAddress(hInst,"maxdg");
check = maxdg(pudataarray,row,col,path,Vlimit,Ilimit,PF,PFtype,Ibase);
FreeLibrary(hInst);

[/code]

dll是由VC 6撰寫的,每次的執行時間約為30秒到2分鐘

這時候我的主畫面滑鼠會變漏斗、有些畫面也會反白

因為迴圈是寫在dll裡,所以我用這個指令Application->ProcessMessages()

好像沒有用,請問怎麼才行解決反白的問題,謝謝!
boss.tw
高階會員


發表:15
回覆:109
積分:194
註冊:2005-05-17

發送簡訊給我
#2 引用回覆 回覆 發表時間:2010-04-17 17:23:29 IP:122.116.xxx.xxx 訂閱
編輯記錄
boss.tw 重新編輯於 2010-04-17 17:23:51, 註解 無‧
maplefog
一般會員


發表:16
回覆:24
積分:13
註冊:2008-11-08

發送簡訊給我
#3 引用回覆 回覆 發表時間:2010-04-17 19:42:07 IP:140.118.xxx.xxx 訂閱

我研究了一下Thread

程式碼現在改成這樣

.h檔加這個

[code cpp]
class TMyThread : public TThread
{
public:
__fastcall TMyThread(void);

private:
void __fastcall Execute(void);
};

[/code]

.cpp 原本內容

[code cpp]
void __fastcall TForm1::MaxDG(double Vlimit,double Ilimit,double PF,int PFtype)
{
int check = 1;
double Sbase = 100;
int a = dFind(settingdata,1,2);
double Vbase = settingdata[a][8];
double Ibase = Sbase*1000/Vbase/sqrt((double)3);

AnsiString pathx = exepath "dll\\maxdg.dll";
AnsiString pathy = exepath "dll\\";
SetCurrentDirectory(pathy.c_str());

const int row = pudata.size();
const int col = pudata[0].size();
double *pudataarray = new double[row*col];

for(int j=0;j!=col; j)
for(int i=0;i!=row; i)
pudataarray[i j*row] = pudata[i][j];
char *path = exepath.c_str();

int (*maxdg)(double *,const int,const int,char *,double,double,double,int,double);
HINSTANCE hInst = LoadLibrary(pathx.c_str());
(FARPROC &)maxdg = GetProcAddress(hInst,"maxdg");
check = maxdg(pudataarray,row,col,path,Vlimit,Ilimit,PF,PFtype,Ibase);
FreeLibrary(hInst);
delete [] pudataarray;

if(check==0)
{
/*
BusFlow.clear();
LineFlow.clear();
Loss.clear();
FunFlow();

TForm30 *F30 = new TForm30(Application);
Form30 = F30;
Form29->Visible = false;
Form30->ShowModal();
*/
}
}

[/code]

現在改成

[code cpp]
void __fastcall TForm1::MaxDG(double Vlimit,double Ilimit,double PF,int PFtype)
{
double Sbase = 100;
int a = dFind(settingdata,1,2);
double Vbase = settingdata[a][8];
double Ibase = Sbase*1000/Vbase/sqrt((double)3);

AnsiString pathx = exepath "dll\\maxdg.dll";
AnsiString pathy = exepath "dll\\";
SetCurrentDirectory(pathy.c_str());

const int row = pudata.size();
const int col = pudata[0].size();
double *pudataarray = new double[row*col];

for(int j=0;j!=col; j)
for(int i=0;i!=row; i)
pudataarray[i j*row] = pudata[i][j];
char *path = exepath.c_str();

MyThread = new TMyThread;
delete [] pudataarray;


/*
BusFlow.clear();
LineFlow.clear();
Loss.clear();
FunFlow(); TForm30 *F30 = new TForm30(Application);
Form30 = F30;
Form29->Visible = false;
Form30->ShowModal();
*/
}
//---------------------------------------------------------------------------
//=======================================================
// TMyThread 程序開始
//=======================================================
__fastcall TMyThread::TMyThread(void):TThread(true)
{
Resume();
}
//-------------------------------------------------------
void __fastcall TMyThread::Execute(void)
{
int check = 1;
FreeOnTerminate = true;
if(!Terminated)
{
int (*maxdg)(double *,const int,const int,char *,double,double,double,int,double);
HINSTANCE hInst = LoadLibrary(pathx.c_str());
(FARPROC &)maxdg = GetProcAddress(hInst,"maxdg");
check = maxdg(pudataarray,row,col,path,Vlimit,Ilimit,PF,PFtype,Ibase);
FreeLibrary(hInst);
}
if(check==0)
MyThread->Terminate();
}
//=======================================================
// TMyThread 程序結束
//=======================================================
[/code]

現在有點疑惑,怎麼把原本的變數pudataarray,row,col,path,Vlimit,Ilimit,PF,PFtype,Ibase

傳到thread裡。

還有我的終止條件是對的嗎? 在Execute()的最後寫MyThread->Terminate();

感謝!
編輯記錄
maplefog 重新編輯於 2010-04-17 19:51:49, 註解 無‧
maplefog 重新編輯於 2010-04-17 19:53:21, 註解 無‧
boss.tw
高階會員


發表:15
回覆:109
積分:194
註冊:2005-05-17

發送簡訊給我
#4 引用回覆 回覆 發表時間:2010-04-18 16:38:08 IP:122.116.xxx.xxx 訂閱
原本的變數可以在一開始調用 thread 時傳入,也可以用全域變數,也可以用記憶體共享的方式
double *,const int,const int,char *,double,double,double,int,double):TThread(true)


FreeOnTerminate = true; //表示此 Thread 跑完自動結束,自動 Release
所以你不需對它 Terminate

另外避免在 thread 直接對 vcl 元件操作,會有問題
最好是用變數傳遞再改變 vcl
編輯記錄
boss.tw 重新編輯於 2010-04-18 16:40:25, 註解 無‧
maplefog
一般會員


發表:16
回覆:24
積分:13
註冊:2008-11-08

發送簡訊給我
#5 引用回覆 回覆 發表時間:2010-04-19 16:00:51 IP:140.118.xxx.xxx 訂閱

感謝你

弄了好幾天,程式終於變得正常了。

我後來是使用全域變數解決的,

另外又碰到其他問題,就是Thread執行完後需要再執行其它程式

不過後來參考其他文章解決了 感謝。

程式碼如下

.h檔加這個

[code cpp]
class TMyThread : public TThread
{
public:
__fastcall TMyThread(void);

private:
void __fastcall Execute(void);
void __fastcall Start(void);
void __fastcall End(void);
};
//-------------------------------------------------------
class TForm1 : public TForm
{
private: // User declarations
void __fastcall MYThreadEnd(TObject* Sender);
}
//-------------------------------------------------------

[/code]

.cpp檔

[code cpp]
TMyThread *MyThread; //加在TForm1 *Form1;下面

//---------------------------------------------------------------------------
void __fastcall TForm1::MaxDG(void)
{
MyThread = new TMyThread;
MyThread->OnTerminate = MYThreadEnd; //thread結束時執行
}
//---------------------------------------------------------------------------
void __fastcall TForm1::MYThreadEnd(TObject* Sender)
{
MaxDGData.clear();
FunMaxDG();

TForm30 *F30 = new TForm30(Application);
Form30 = F30;
Form30->ShowModal();
}
//---------------------------------------------------------------------------

//=======================================================
// TMyThread開始
//=======================================================
__fastcall TMyThread::TMyThread(void):TThread(true)
{
Resume();
}
//-------------------------------------------------------
void __fastcall TMyThread::Execute()
{
int check = 1;
FreeOnTerminate = true;
if(!Terminated)
{
Synchronize(Start);
double Sbase = 100;
int a = Form1->dFind(Form1->settingdata,1,2);
double Vbase = Form1->settingdata[a][8];
double Ibase = Sbase*1000/Vbase/sqrt((double)3);

AnsiString pathx = Form1->exepath "dll\\maxdg.dll";
AnsiString pathy = Form1->exepath "dll\\";
SetCurrentDirectory(pathy.c_str());

const int row = Form1->pudata.size();
const int col = Form1->pudata[0].size();
double *pudataarray = new double[row*col];

for(int j=0;j!=col; j)
for(int i=0;i!=row; i)
pudataarray[i j*row] = Form1->pudata[i][j];
char *path = Form1->exepath.c_str();

int (*maxdg)(double *,const int,const int,char *,double,double,double,int,double);
HINSTANCE hInst = LoadLibrary(pathx.c_str());
(FARPROC &)maxdg = GetProcAddress(hInst,"maxdg");
check = maxdg(pudataarray,row,col,path,Form1->Vlimit,
Form1->Ilimit,Form1->PF,Form1->PFtype,Ibase);
FreeLibrary(hInst);
delete [] pudataarray;
}
if(check==0)
Synchronize(End);
}
//-------------------------------------------------------
void __fastcall TMyThread::Start()
{
Form1->StatusBar1->SimpleText = " 執行中,請稍候。";
Form2->Enabled = false;
}
//-------------------------------------------------------
void __fastcall TMyThread::End()
{
Form1->StatusBar1->SimpleText = "";
Form2->Enabled = true;
}
//=======================================================
// TMyThread結束
//=======================================================

[/code]




系統時間:2017-12-14 16:08:47
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!