Ada 程式設計/平臺/Windows/Visual C++ - GNAT 介面
本指南介紹了在 Windows 中使用 GNAT 和 MS Visual C++ 從 Ada 連線到 C++ 的方法。
在開始之前,您應該檢查您的環境。以下是編寫本指南時所使用的環境。
- Ada GPL 2006 和 GPS。
- Microsoft Visual Studio 2005
我們將遵循以下步驟
- 編寫您的 Ada 程式碼並構建動態庫
- 建立 .lib 檔案(用於靜態連結)
- 協同工作
- 執行您的程式碼
----------------------------- t.adswithinterfaces.c;packagetispackageCrenamesinterfaces.c;proceduretest(a,b,z,d,e:c.int) ;pragmaexport (stdcall, test, "test");endt;
--------------------------------t.adbwithada.text_io;witht.th;packagebodytisproceduretest(a,b,z,d,e:c.int)ismyd : integer := 0;begint.th.t.getToken (myd); ada.text_io.put_line(myd'img & " and e value is" & c.int'image(e));end;endt;
------------------------------------th.adspackaget.thistaskTisentrygetToken (t :outinteger);end;privated : integer := 0;endt.th;
-------------------------------------th.adbwithada.text_io;packagebodyt.thistaskbodyTisuseada.text_io;beginloopselectacceptgetToken (t :outinteger)dot := d;endgetToken;orterminate;endselect; d := d + 1;endloop;end;endt.th;
最重要的是您的專案檔案。它讓您更容易。
project Testdll is
for Library_Name use "Te";
for Library_Dir use "dll";
for Library_Ali_Dir use "ali";
for Library_Kind use "dynamic";
for Languages use ("Ada");
for Object_Dir use "obj";
for Library_Interface use ("t");
for Library_Auto_Init use "False";
for Library_Src_Dir use "dll";
end Testdll;
您可以在 GPS IDE 中配置幾乎所有設定。但請注意,GPS 無法正確進行 Library_Interface 設定。配置完成後,您應該檢查專案檔案並相應地修改它。Library_Interface 指的是 DLL 中包含匯出函式的包。
Library_Auto_Init 很有趣,您必須在專案中選擇一個正確的設定。
如果選擇 True,則庫載入時將呼叫 adaInit(這意味著細化會在載入時間自動出現);如果選擇 False,則會在 DLL 中匯出 init 和 finalize 函式,您必須自己呼叫它們。
如果您匯出像 C/C++ "普通" 函式一樣的函式,沒有任何細化部分,則可以將 library_auto_init 設定為 True。
如果您的 Ada 程式碼不僅僅像 C/C++ 一樣工作,而且還需要 Ada 細化函式,那麼您應該自己進行初始化/結束處理。
"危險" 危險" 危險" 危險" 危險"
例如,如果您有一個庫級任務需要在載入時間進行細化,並且使用隱式連結並載入它,那麼當 DllMain 呼叫 init 程式碼時,它將 "死鎖等待"。這是一種您不希望出現的意外行為。
危險" 危險" 危險" 危險" 危險"
在某些情況下,您可以使用 LoadLibrary / GetProcAddress 來工作(顯式載入)。但這並不容易管理您的程式碼,尤其是在匯出許多函式的情況下。
您可以使用實用程式 dumpbin 和 lib 來生成 .lib 檔案(2.A)
dumpbin/exports Te.dll > te.def,
檔案內容是
Microsoft (R) COFF/PE Dumper Version 8.00.50727.42 Copyright (C) Microsoft Corporation. All rights reserved.
檔案 te.dll 的轉儲
File Type: DLL
Section contains the following exports for Te.dll
00000000 characteristics
44E2ABD2 time date stamp Wed Aug 16 13:23:30 2006
0.00 version
1 ordinal base
19 number of functions
19 number of names
ordinal hint RVA name
1 0 00001461 Tefinal
2 1 000011A0 Teinit
3 2 00005130 _CRT_MT
4 3 000050E0 t_E
5 4 000050D0 t__th_E
6 5 0000155F t__th__P2sIP
7 6 00007040 t__th___chain
8 7 00001745 t__th___elabb
9 8 0000156E t__th___elabs
10 9 00007044 t__th___master
11 A 000050D8 t__th__d
12 B 00007048 t__th__t
13 C 00006010 t__th__tT1
14 D 000016B9 t__th__tTKB
15 E 000050D1 t__th__tTKE
16 F 00001490 t__th__tTKVIP
17 10 000050D4 t__th__tTKZ
18 11 00005000 temain_E
19 12 0000178F test@20
Summary
1000 .bss
1000 .data
1000 .edata
2000 .idata
1000 .rdata
1000 .reloc
2E000 .stab
E3000 .stabstr
4000 .text
(2.b) 刪除 Te.def 中的所有內容,但保留...
EXPORTS
Tefinal
Teinit
_CRT_MT
t_E
t___elabb
t__th_E
t__th__P2sIP
t__th___elabb
t__th__d
t__th__tB
t__th__tE
t__th__tVIP
t__th__tZ
temain_E
test@20
Teinit 和 Tefinal 用於在 Te.dll 載入後細化和終止 Ada 細化部分。(名稱不叫 adainit/adafinalize,但仍然是 adainit/adafinalize 的相同函式)
啟動 Visual Studio C++ 專案,並將 Te.lib 新增到連結器設定中。
編寫一個 Te.h 標頭檔案用於 Ada DLL(GPS 應該為您生成 .lib 和 .h)。
extern "C" extern void _stdcall test(int a,int b,int c,int d,int e);
extern "C" extern void Teinit();
extern "C" extern void Tefinal();
並編寫一個 C/C++ 測試程式碼來生成一個 .exe 檔案。
#include "stdafx.h" //visual c++ default header
#include "Te.h" //your ada library header
int _tmain(int argc, _TCHAR* argv[])
{
Teinit(); //start init
for (int i = 0 ; i< 300 ;i++)
test(0,0,0,0,i);
Tefinal(); //end init
return 0;
}
將 .exe 和 .dll 放置在同一個目錄中並執行測試。
載入程式將按照以下順序查詢 dll:
- 當前目錄
- path 變數
- Windows 目錄
將 dll 和 exe 放置在同一個目錄中,這是最好的選擇。
