- 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