深入浅出CChart 每日一课——快乐高四第三十二课 重振天鹰教,BCB直接调用Dll版的CChart

上一课是Delphi直接调用CChart的Dll,不用ActiveX控件。对于C++ Builder来说,由于采用的语言是C++,那调用Dll版的CChart就更没问题了。

实际上,虽然都是C++,但C++ Builder还不能直接引用Chart.h。VC和C++ Builder在很多方面的处理都不相同,看起来简单直接的方法不行,还是得老老实实地像Delphi那样,导出函数后再使用。

在C++ Builder里面,导出函数的方法相对Delphi略微复杂一些,需要显式加载Dll文件。

下面给出例子。

第一步,打开BCB6,将自动建立Form1窗体。点击菜单“File”->“Save Project As…”,保存文件LessonA32文件夹。

第二步,通过Object Inspector添加Form1的OnCreate函数、OnDestroy函数和OnResize函数。

第三步,在Unit1.cpp文件里,TForm1 *Form1;这一行的前面,添加如下代码。

typedef void (*pCreateChart)();
typedef int (*pAttach)(HWND hWnd);
typedef void (*pSetTitle)(wchar_t *title);
typedef int (*pAddPoint2D)(double x, double y, int nDataIndex, int nPlotIndex);
typedef bool (*pSetConfineRect)(RECT rect);
typedef void (*pReDraw)();

HMODULE hDLL = 0;

这是后面要从CChartu.dll里面导出函数的原型。

为了能导出函数,需要先把CChartu.dll拷贝到LessonA32文件夹里。

这里还设置了一个全局的模块句柄hDLL,用于保存显式加载Dll文件后的句柄。

第四步, 修改OnCreate函数如下。

void __fastcall TForm1::FormCreate(TObject *Sender)
{
    hDLL = LoadLibrary("CChartu.dll");
    if(hDLL)
    {
        pCreateChart CreateChart = pCreateChart(GetProcAddress(hDLL, "?CreateChart@Classless@@YAXXZ"));
        pAttach Attach = pAttach(GetProcAddress(hDLL, "?Attach@Classless@@YAHPAUHWND__@@@Z"));
        pSetTitle SetTitle = pSetTitle(GetProcAddress(hDLL, "?SetTitle@Classless@@YAXPB_W@Z"));
        pAddPoint2D AddPoint2D = pAddPoint2D(GetProcAddress(hDLL, "?AddPoint2D@Classless@@YAHNNHH@Z"));
        pSetConfineRect SetConfineRect = pSetConfineRect(GetProcAddress(hDLL, "?SetConfineRect@Classless@@YA_NUtagRECT@@@Z"));

        if(!CreateChart || !Attach || !SetTitle || !AddPoint2D || !SetConfineRect)return;

        CreateChart();
        Attach(Form1->Handle);
        for(int i=-10; i<=10; i++)
        {
            AddPoint2D(i, i*i, 0, 0);
        }
        SetTitle(L"C++ Builder标题");
    }
}

这里先显式加载CChartu.dll,然后从里面导出了要用到的几个函数。然后在调用相应的函数实现我们需要的功能。

第五步,修改OnDestroy函数如下。

void __fastcall TForm1::FormDestroy(TObject *Sender)
{
    if(hDLL)
    {
        FreeLibrary(hDLL);
    }
}

第六步,修改OnResize函数如下。

void __fastcall TForm1::FormResize(TObject *Sender)
{
    if(hDLL)
    {
        pReDraw ReDraw = pReDraw(GetProcAddress(hDLL, "?ReDraw@Classless@@YAXXZ"));
        if(!ReDraw)return;
        ReDraw();
    }
}

同样是先导入函数再调用。

深入浅出CChart 每日一课——快乐高四第三十二课 重振天鹰教,BCB直接调用Dll版的CChart

本节课到此结束。

上一篇:JavaScript类型相关常用操作


下一篇:JAVA中用StopWatch计算代码耗时的方法