- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I can get the C_Calling_Fortran Sample working. no problem.
so to keep the issue simple, itry to createa module anda common to'share' data between the C++ and fortranprograms, it compiles & links fine, but no sharing. (global items in C++ undefined on debug browse)
I've tried uppercase, lowercase, mentalcase! underscore, before/after/etc.
Could someone give me a hint as towhat i'm doing wrong?
thank you.
[bash]cmain.cpp
#include
#include
#include "test1.h"
#ifdef __cplusplus
extern "C"
#endif
#ifdef USEDLL
__declspec(dllimport)
#endif
void FSUB
(int *INT_ARG,
char *STR_IN,
char *STR_OUT,
size_t STR_IN_LEN,
size_t STR_OUT_LEN);
void main (int argc, char *argv[])
{
char instring[40];
char outstring[40];
int intarg;
strcpy_s(instring,"Testing...");
intarg = 123;
/* Call Fortran routine - pass intarg by reference,
pass length of outstring explicitly */
FSUB(&intarg,instring,outstring,strlen(instring),sizeof(outstring));
printf(" %f %i %i %f %i %i", EXAMP.A, EXAMP.I1, EXAMP.I2, COMMON_EXAMP.AA, COMMON_EXAMP.II1, COMMON_EXAMP.II2);
EXAMP.A = 0.;
EXAMP.I1 = 0.;
EXAMP.I2 = 0.;
COMMON_EXAMP.AA = 0.;
COMMON_EXAMP.II1 = 0.;
COMMON_EXAMP.II2 = 0.;
printf(" %f %i %i %f %i %i", EXAMP.A, EXAMP.I1, EXAMP.I2, COMMON_EXAMP.AA, COMMON_EXAMP.II1, COMMON_EXAMP.II2);
printf("%s\n",outstring);
}
file test1.h
extern "C"
{
struct EXAMP
{
float A;
int I1;
int I2;
} EXAMP;
struct COMMON_EXAMP
{
float AA;
int II1;
int II2;
} COMMON_EXAMP;
}
file fsub.f90
MODULE EXAMP
IMPLICIT NONE
SAVE
REAL(4) :: A
INTEGER(4) :: I1
integer(4) :: I2
END MODULE EXAMP
SUBROUTINE FSUB (INT_ARG, STR_IN, STR_OUT)
use examp
IMPLICIT NONE
SAVE
REAL(4) AA
INTEGER(4) :: II1, II2
COMMON / COMMON_EXAMP / AA,II1,II2
!DEC$ ATTRIBUTES DLLEXPORT :: FSUB
INTEGER, INTENT(IN) :: INT_ARG
CHARACTER(*), INTENT(IN) :: STR_IN
CHARACTER(*), INTENT(OUT) :: STR_OUT
CHARACTER*5 INT_STR
WRITE (INT_STR,'(I5.5)')INT_ARG
A = 12.
I1 = 22
I2 = 33
AA = 13.
II1 = 24
II2 = 34
STR_OUT = STR_IN // INT_STR // CHAR(0)
RETURN
END [/bash]
[bash]and the command lines (for quick check) for fortran compile
/nologo /debug:full /Od /names:uppercase /module:"Debug/" /object:"Debug/" /traceback /check:bounds /libs:dll /threads /dbglibs /c
fortran link
/OUT:"..\USEDLL/FDLL.dll" /INCREMENTAL:NO /NOLOGO /MANIFEST /MANIFESTFILE:"C:\Source09\misc\mixedlanguage\C_calls_Fortran\USEDLL\FDLL.dll.intermediate.manifest" /DEBUG /PDB:"..\USEDLL/FDLL.pdb" /SUBSYSTEM:WINDOWS /IMPLIB:"..\USEDLL/FDLL.lib" /DLL
c++ compile:
/Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "USEDLL" /D "_VC80_UPGRADE=0x0710" /D "_MBCS" /Gm /EHsc /RTC1 /MDd /Fo"Debug\\" /Fd"Debug\vc90.pdb" /W3 /nologo /c /Wp64 /ZI /TP /errorReport:prompt
C++link
/OUT:"Debug/USEDLL.exe" /INCREMENTAL /NOLOGO /MANIFEST /MANIFESTFILE:"Debug\USEDLL.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"Debug/USEDLL.pdb" /SUBSYSTEM:CONSOLE /DYNAMICBASE:NO /MACHINE:X86 /ERRORREPORT:PROMPT fdll.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
[/bash]
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't think you can use extern "C" the way you did - in any case it doesn't work. If you put extern "C" before each struct, it does. Or look at my revised version which uses C interoperability features. (It isn't a full-on C interop example, though, which would require some changes to the way character arguments are handled.)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I know that the nicest thing to do would be to take your program, edit it, and repost it, but I don't really have the time to do that :-(
Couple of things; Just because the module is named "examp" does not mean there exists a struct-like entity named "examp". Moduleshave data*plus* derived type declarations, interface declarations, etc. Moreover, the data is individually declared, and may or may not be declared in the same order you wrote them. In your C program, you're only referencing your own copy of the struct examp.
Now the COMMON block *does* havea struct-like entity (in a very loose way of course) however, you have not exported its name from the DLL.
Thetool I use when I'm trying to reconcile names between C and Fortran is the linker. That is, I would issue the command:
link -dump -symbols fsub.obj (( or fsub.lib after your DLL has been built ))
and look for the name Fortran created. You can, of course, use the same link command on the C object and then work towards reconciliation.
Finally, please take a peek at the mixed language program chapters in the online documentation for more help. You might also want to research the iso_c_binding module to further help with C interoperability; this gives the bonus of being standard too.
- Lorri
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve, Lorri,
Thank you both for the prompt responses. I will tinker and see which works best.
The main thing i'm looking into is data sharing betwen C++ and Fortran rather than passing arguments. I started with the C_Calling_Fortran example and tried to expand on it to see if a module share and a common share could be added and what's strength/weakness of each. The documentation sometimes gives conflicting/confusing/it was too late to be absorbingrecommendations/techniques.
Once i resolve I'lladd a project to the thread with a working copy/sample project with both types of shares (modules and common)
burned a wee bit too much midnight oil last night spinning my wheels!
Thanks again!
Brian
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page