2014-05-13 23 views
3

我有DLL函數在TClientDataSet上執行,如要加載的設置文件以及加載和保存文件。在Delphi應用程序中訪問DLL中加載的TClientDataset的內容

unit dll_dmunit; 

interface 

uses 
    System.SysUtils, System.Classes, Data.DB, Datasnap.DBClient, Vcl.Dialogs,Vcl.DBGrids; 

type 
    TStudentModule = class(TDataModule) 
    StudentSet: TClientDataSet; 
    StudentSource: TDataSource; 
    StudentSetNAME: TStringField; 
    StudentSetID: TIntegerField; 
    StudentSetAGE: TIntegerField; 
    StudentSetSLNo: TAutoIncField; 
    dlgOpen: TOpenDialog; 
    dlgSave: TSaveDialog; 
    private 
    { Private declarations } 
    public 
    end; 

    function loadfile:tdbgrid;stdcall; 
    procedure setfile(fname:string);stdcall; 
    procedure savefile;stdcall; 

var 
    StudentModule: TStudentModule; 
    filename:string; 
    grid:TDBgrid; 

const 
    path:string='C:\Users\GlobalLogic\Documents\RAD Studio\Projects\Student\test.cds'; 

implementation 

{%CLASSGROUP 'Vcl.Controls.TControl'} 

{$R *.dfm} 

    procedure setfile(f_name: string);stdcall; 
    begin 
    filename:=f_name; 
    end; 

    function loadfile:tdbgrid;stdcall; 
    var 
    _xmldata:string; 
    begin 
    StudentModule := TStudentModule.Create(nil); 
    grid:=TDBGrid.Create(nil); 
    result:=grid; 
    try 
    filename:='C:\Users\GlobalLogic\Documents\RAD Studio\Projects\Student\test.cds'; 
    StudentModule.StudentSet.LoadFromFile(filename); 
    grid.DataSource:=StudentModule.StudentSource; 
    _xmldata :=StudentModule.StudentSet.XMLData; 
    result:=grid; 
    finally 
    StudentModule.Free; 
    end; 
    showmessage('End of the function'); 
    end; 

    procedure savefile;stdcall; 
    begin 
    StudentModule.StudentSet.SaveToFile(filename); 
    end; 
end. 

我能夠執行的loadFile方法,但現在我需要在TClientDataSet的內容導出到Delphi應用程序。爲此,我試圖獲取TDbgrid中的內容,然後將此對象返回到應用程序層,但我無法這樣做。 然後我嘗試讀取XML格式,但無法理解如何傳遞和解碼XML格式。我需要將加載的數據集的內容移動到我想要顯示數據的應用程序中。 請幫我這樣做。 謝謝

+2

您無法跨DLL邊界傳遞Delphi對象。通過跨DLL邊界使用字符串,你已經弄錯了。你似乎在尋找的是運行時軟件包。如果放棄單獨的模塊並將所有代碼編譯到可執行文件中,它會讓你的生活變得更加輕鬆。 –

+0

@ DavidHeffernan - 我是這門語言的新手,所以我無法理解您的回答,您可以幫助我解決一些代碼或鏈接,這些代碼或鏈接可以讓我更好地理解您所談論的概念。 –

+0

直到我知道你的目標和要求是什麼時,我才真正想進入更多的細節。 –

回答

1

下面是一個簡單的實現,應該做你想要的,而不必從你的dll導出對象,這往往是有點尷尬。相反,只需導出包含數據的XML字符串即可。

重要的一點是您的導出函數的簽名(在本例中爲function ExportXML:pwideChar;)和dllexport部分。 確保將您的XML數據導出爲pwidechar

var Xmldata:widestring; 
... 
function loadfile... 
... 
Xmldata :=StudentModule.StudentSet.XMLData; 

function ExportXML:pwideChar;stdcall; 
begin 
    result:= pwideChar(Xmldata); 
end; 

exports 
    ExportXML name 'ExportXML'; 

在你的應用程序只需將DLL調用ExportXML的結果加載到TClientDataSet實例,並把它插入到你的管制。

有關使用dll的exports部分的更多方式,請參閱Using Export Clause in Libraries,這似乎是您錯過的部分。

順便說一句,如果您要從德爾福到德爾福,,您不需要stdcall指令。請參閱:

If you want your library to be available to applications written in other languages, 這是最安全的在出口 函數的聲明指定STDCALL。其他語言可能不支持Delphi的默認寄存器 調用約定。

+1

而不是使用全局變量,它更容易返回一個'WideString'。由於[不同編譯器之間的ABI差異](http://stackoverflow.com/questions/9349530/why-can-a-widestring-not-be-used-as-a-function-return-value-for-interop) ,這更好地作爲out參數完成。我會聲明這樣的函數:'procedure ExportXML(const Intput:WideString; out Output:WideString); stdcall;' –

+0

@DavidHeffernan - 同意。我不想深究這一切。我只是向那裏提出了或多或少符合問題中使用的代碼的內容,以給出核心答案。重構等 - 這是另一回事。 – Vector

相關問題