1. 程式人生 > >使用Delphi宣告C++帶函式的結構體實戰

使用Delphi宣告C++帶函式的結構體實戰

typedef struct tagRecord
{
 int val;
 int getvalplus()
 {
  val++;
  return val;
 }
}TRecord, *PRecord; 

    帶函式的結構體!面對這個面目猙獰的傢伙,我開始無所適從,狂在GOOGLE、BAIDU裡通過關鍵字“Delphi 帶函式的記錄型別”、“Delphi C++ 結構體 函式”、“Delphi record function”......結果都是無功而返。

    一邊搜尋,還一邊通過編碼測試來尋找問題解決門道。起初我嘗試效仿採用函式指標的方式,結果函式體無法實現,更不用說訪問結構體其他成員了。

    後面又一次試著採用class而非record型別來宣告:

 PRecord = ^TRecord;
  TRecord = class
  public
    val: integer;
    function getvalplus():integer;
  end;
     

    在介面部分:function ShowValue(rcd: PRecord):integer;stdcall;external 'Structdll.dll';

    引數rcd無論宣告為PRecord還是Pointer,傳遞進去之後debug調試出來的值根本就不對,疑似某物件的地址之類的數字。去俺們圈子的技術群裡請教高手結果還引來“變態、真賤”的一頓罵,哪兒有這麼用的?不吃飽了撐得嗎?那你就考慮考慮採用代理模式來迂迴解決吧!......這個時候,我幾乎絕望了,特別無助,我的印象裡,在Win32開發這片沃土裡,Delphi和C++本就一脈相承的啊,但面對這個細節的時候我發現原來景色並不是那麼美好。

    無奈之下到CSDN社群的Delphi->API板塊發帖提問,這時也臨近中午,吃了幾口麵包,吞了兩缸涼白開睏意來了,撂倒就是一覺......哪知一覺醒來發現有人回帖了,雖然他在D2007上驗證通過,但我還是抱著試試看的想法在D7上開始測試。沒成想,嘿!果然有效哎!你看看:

    在dll庫裡的宣告(C++):

typedef struct tagRecord
{

 int val;
 int getvalplus()
 {
  val++;

  return val;
 }
}TRecord, *PRecord;

extern "C" __declspec(dllexport

int __stdcall ShowValue(TRecord *rcd)
{

 int val = rcd->getvalplus();
 CString ss = _T("");
 ss.Format("Value is:%d", val);
 AfxMessageBox(ss);

 return 0;
}

    在D7中的宣告:

type
  
PRecord = ^TRecord;
  TRecord =
 Object
  
public
    val: integer;
    function getvalplus():integer;
  end;


function ShowValue(rcd: PRecord):integer;stdcall;external 'Structdll.dll';

implementation

function TRecord.getvalplus():integer;
begin
  val := val + 1;
  Result := val;

end;

在D7中的呼叫:    

procedure TfrmMain.Button1Click(Sender: TObject);
var
  r: TRecord;
  pr: PRecord;

begin
  r.val := 10;
  pr := @r;
  r.getvalplus;
  ShowMessage(inttostr(r.val));
  ShowValue(pr);

end;

後記:以前在DOS下,以C/C++為主,Pascal只用過Turbo Pascal4.0,對以後Pascal的版本並不十分了解,今天看了網友housisong的留言,才知道我所謂的新功能--有限棧物件,Delphi中早就有了,如Delphi7.0就可以使用Object關鍵字定義棧物件,而且比2007的record型別還完善一些,record不能繼承,而object物件能夠繼承,看來我真是孤陋寡聞了!!!