Ada 编程/平台/Windows/Visual C++ - GNAT 接口
本指南介绍了在 Windows 中使用 GNAT 和 MS Visual C++ 从 Ada 连接到 C++ 的方法。
在开始之前,您应该检查您的环境。以下是编写本指南时所使用的环境。
- Ada GPL 2006 和 GPS。
- Microsoft Visual Studio 2005
我们将遵循以下步骤
- 编写您的 Ada 代码并构建动态库
- 创建 .lib 文件(用于静态链接)
- 协同工作
- 运行您的代码
----------------------------- t.adswith
interfaces.c;package
tis
package
Crenames
interfaces.c;procedure
test(a,b,z,d,e:c.int) ;pragma
export (stdcall, test, "test");end
t;
--------------------------------t.adbwith
ada.text_io;with
t.th;package
body
tis
procedure
test(a,b,z,d,e:c.int)is
myd : integer := 0;begin
t.th.t.getToken (myd); ada.text_io.put_line(myd'img & " and e value is" & c.int'image(e));end
;end
t;
------------------------------------th.adspackage
t.this
task
Tis
entry
getToken (t :out
integer);end
;private
d : integer := 0;end
t.th;
-------------------------------------th.adbwith
ada.text_io;package
body
t.this
task
body
Tis
use
ada.text_io;begin
loop
select
accept
getToken (t :out
integer)do
t := d;end
getToken;or
terminate
;end
select
; d := d + 1;end
loop
;end
;end
t.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 放置在同一个目录中,这是最好的选择。