Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Send email from CVF console app?

Intel_C_Intel
Employee
2,072 Views
I am writing a program that runs daily on a remote machine. I would like it to email me when it completes each day's run. It doesn't need to be elaborate, just 1 line of text to a prespecified address through a prespecified smtp server.

I have figured out I will have to use the MAPI functions (mapiSendMail, mapiMessage, etc).

I have two questions before I go any further on this project:
(1) has anyone already done something like this & would they share the code with me?
(2) if not, do interfaces to the mapi functions exist in the win32 api modules included in CVF? If so, where, and if not, does anyone have any suggestions?

Matt.
0 Kudos
11 Replies
Steven_L_Intel1
Employee
2,072 Views
The SEE4F library of SMTP/POP3 routines may be of interest, but this is a commercial product. MAPI seems to be implemented using a C++ class library and/or COM server, and thus doesn't have Fortran interfaces readily available. Maybe the Module Wizard would be able to help.

Steve
0 Kudos
james1
Beginner
2,072 Views
You might consider running your program from a script, then having the script generate the e-mail rather than having your program do this directly.

James
0 Kudos
Intel_C_Intel
Employee
2,072 Views
James,

at the risk of sounding silly, how do i send an email with a script?

Matt.
0 Kudos
james1
Beginner
2,072 Views
You can access MAPI through scripting, or use a simple tool I've used for years, BLAT.

James
0 Kudos
Jugoslav_Dujic
Valued Contributor II
2,072 Views
> MAPI
> seems to be implemented using a C++ class library
> and/or COM server, and thus doesn't have Fortran
> interfaces readily available. Maybe the Module
> Wizard would be able to help.

AFAIK that is not entirely true -- take a look at MAPI.h for example. It seems that MAPI.h defines only stuff compatible with old Windows (i.e. basic e-mail functionality), but that's what OP essentially wants. As I see, it's not translated to Fortran even in 6.6 but since it's a straightforward C header, it should be simple to convert.

Jugoslav

0 Kudos
fritsv
Beginner
2,072 Views
Note that BLAT is also available as a Fortran callable
DLL. Not for the latest version afaik. But works quite well.

Frits.
0 Kudos
Intel_C_Intel
Employee
2,072 Views
fritsv,

In a nutshell, how would I call the .dll? I've never used cross-platform .dll's before. I have the 1.84e release which has all of the files.

I've added the .lib to my project, but I can't find a description of the function in the .dll, nor how I add the dll to the project.

Could you help?

TIA,

matt.
0 Kudos
Intel_C_Intel
Employee
2,072 Views
Why don't I add a few details:

I have added the interface
INTERFACE
INTEGER(4) FUNCTION SEND(TXT)
!DEC% ATTRIBUTES DLLIMPORT
CHARACTER(LEN=*) TXT
END FUNCTION
END INTERFACE

to the proper place in the calling subroutine. I have added blatdll.dll and blatdll.lib to the list of source files (I can't find anywhere else to put them, and my version of VS seems finicky about letting me open the included project file)

With all this, when I compile my app, I get a LINKER error of unresolved external symbol: -send@8

I am sure that this is a simple oversight, but I'd appreciate any help.

Thanks,
matt.
0 Kudos
Jugoslav_Dujic
Valued Contributor II
2,072 Views
You need:
INTERFACE 
INTEGER(4) FUNCTION SEND(TXT)
!DEC% ATTRIBUTES DLLIMPORT, ALIAS: "Something":: SEND
CHARACTER(LEN=*) TXT
END FUNCTION
END INTERFACE

Where you should put an actual exported name instead of "Something" (NB: case-sensitive). You can obtain it using
dumpbin /exports blatdll.dll
. It will probably be "_Send@4" or "_send".

If it's exactly "_Send@4" you should add
!DEC$ATTRIBUTES REFERENCE:: TXT
line in the INTERFACE block. (@4 indicates there's only one argument, thus no string length should be passed).

Jugoslav
0 Kudos
Jugoslav_Dujic
Valued Contributor II
2,072 Views
...that should be !DEC$, not !DEC% of course.

Btw, I played today with Simple MAPI module (mapi.h -> mapi.f90). Simple MAPI is straightforward C and easily translatable to Fortran -- only gotcha is that dynamic binding is necessary (i.e. no import library is provided).
So, you can find mapi.f90 along with a sample use on my home page.

Jugoslav
0 Kudos
fritsv
Beginner
2,072 Views
Here a sample program:

Program Example
use dfwin, only: loadlibrary,getprocaddress,freelibrary
use dflib

! Declare an interface block to the routine to be called.
interface
	   integer function send(c)
	   character*(*) c
	   end function
end interface

character(255) command
character(255) line

pointer (p,i)
pointer (q,send)
logical status
integer istat

line='blat.dll'
line=line(1:len_trim(line))//char(0)
! First, locate and load the dll 
p = loadlibrary(line)
if (p == 0) then
	type *, "Error occurred opening "//line(1:len_trim(line))
	call sleepqq(5)
	type *, "Program aborting"
	goto 1000
endif

! Set up a pointer to the routine of interest
q = getprocaddress(p, "Send"C)
if (q == 0) then
	type *, "Error occurred finding SEND in "//line(1:len_trim(line))
	call sleepqq(5)
	type *, "Program aborting"
	goto 1000
endif

command='... The commandline for Blat ...'//char(0)

! Now call the routine 
istat=send(command)
type *,'Send status:',istat
status = freelibrary(p)

1000 stop

end


Frits.
0 Kudos
Reply