From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,XPRIO autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,5f8c8c02a4c181d3,start X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news3.google.com!newsfeed.stanford.edu!newsfeed.news.ucla.edu!newsfeed.media.kyoto-u.ac.jp!Spring.edu.tw!news.nctu.edu.tw!feeder.seed.net.tw!netnews!not-for-mail From: "bubble" Newsgroups: comp.lang.ada Subject: ada dll and c++ work together easy guide Date: Wed, 16 Aug 2006 16:58:35 +0800 Organization: HiNetNews Message-ID: NNTP-Posting-Host: 211.21.60.18 X-Trace: netnews.hinet.net 1155718599 14034 211.21.60.18 (16 Aug 2006 08:56:39 GMT) X-Complaints-To: usenet@HiNetnews.hinet.net NNTP-Posting-Date: Wed, 16 Aug 2006 08:56:39 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.2869 X-RFC2646: Format=Flowed; Original X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2962 Xref: g2news2.google.com comp.lang.ada:6224 Date: 2006-08-16T16:58:35+08:00 List-Id: dear all, I just want to share some of my experience about MS visual C++ work with ada. if possible,please modify it and put it in ada wiki. before start,you should check your environment. It is my work environment. 1. Ada GPL 2006 and GPS. 2. microsoft visual studio 2005 please follow the steps. 1. write your ada code and build dynamic library. 2. make a .lib file (for static linking) 3. work together 4. run your code. step 1. source code. ----------------------------- t.ads with interfaces.c; package t is package C renames interfaces.c; procedure test(a,b,z,d,e:c.int) ; pragma export (stdcall, test, "test"); end t; --------------------------------t.adb with ada.text_io; with t.th; package body t is 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.ads package t.th is task T is entry getToken (t : out integer); end; private d : integer := 0; end t.th; -------------------------------------th.adb with ada.text_io; package body t.th is task body T is 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; ------------------------------------- and most important thing is your project file. It make you more easy. 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; of course, you can config all settings in your GPS IDE(almost). be careful,the GPS can not do Library_Interface setting correctly. after configure it , you should check the project file and modify it. Library_Interface means which package contain export functions in DLL. Library_Auto_Init is interesting and you must choose a correct setting in your project. if choose True, it will call adaInit when library load. (which means elaboration appear in loading time automaticly ) if choose False, it will export init and finalize functions in DLL and you must call them by yourself. if you export function like C/C++ "normal" function without any elaboration parts, you may set library_auto_init to True. if your ada code not only work like C/C++ but also need Ada elaboration function. you should initialize/finalize by yourself. "DANGEROUS" DANGEROUS" DANGEROUS"DANGEROUS"DANGEROUS" for example, if you has library level task need to elaboration in load time and use implied linking and loading it will "deadlock WAITING" when DllMain call init code It's unexpected behaviour that you don't want to. DANGEROUS"DANGEROUS"DANGEROUS"DANGEROUS"DANGEROUS" in some case , you may use LoadLibrary / GetProcAddress to work (Explicit loading). It is not easy to management your code,especially you export many functions . 2. make a .lib file (for static linking) you can use utilities dumpbin and lib to generate .lib file (2.A) dumpbin/exports Te.dll > te.def, the file file content is Microsoft (R) COFF/PE Dumper Version 8.00.50727.42 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file 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) remove all in Te.def but leave ... 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 The Teinit and Tefinal is used to elaborate and terminate the Ada elaboration part after Te.dll loaded. (the name does not call adainit/adafinalize but still the same function as adainit/adafinalize) 3. work together in MS VC++ start visual stdio c++ project and add Te.lib to your linker setting. writing a Te.h header for Ada DLL (the GPS should generate .lib and .h for you ^^; ). 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(); and write a c/c++ test code to generate a .exe file #include "stdafx.h" #include "Te.h" #include #include 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; } 4. run your code. put .exe and .dll in the same directary and run the test the loader will find dll follow the sequence 1. current directory 2. path variable 3. winodws directory put the dll and exe in the same directary is better