- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Steve,
I have tried to create a mixed program from fotran 2003 book.
First, I created a C function in Visual C++ 2008 express,
Second, Icreate a main program in XE2011,and add the path of C object.
However, it failed:
Error1 error LNK2019: unresolved external symbol __imp__C referenced in function _MAIN__
If C++ and Fotran XE2011 are not in the same platform, Is that possible to link them together?
Best regards
Xianfa
I have tried to create a mixed program from fotran 2003 book.
First, I created a C function in Visual C++ 2008 express,
Second, Icreate a main program in XE2011,and add the path of C object.
However, it failed:
Error1 error LNK2019: unresolved external symbol __imp__C referenced in function _MAIN__
If C++ and Fotran XE2011 are not in the same platform, Is that possible to link them together?
Best regards
Xianfa
Link Copied
13 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You will have to show the code you are using. Otherwise we can only make a wild guess.
Regards,
Arjen
Regards,
Arjen
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>First, I created a C function in Visual C++ 2008 express,
Second, Icreate a main program in XE2011,and add the path of C object.
However, it failed.
There are only a few ways of making the two languages work together. The one most recommended at this time is to use the Fortran 2003 C-Interoperability feature.
On the other hand, there are many ways of failing to make the two languages work together, and we do not know which of those you have tried.
>If C++ and Fotran XE2011 are not in the same platform, Is that possible to link them together?
If the objects are for different OS or architecture targets, with rare exceptions they cannot be linked together.
Second, Icreate a main program in XE2011,and add the path of C object.
However, it failed.
There are only a few ways of making the two languages work together. The one most recommended at this time is to use the Fortran 2003 C-Interoperability feature.
On the other hand, there are many ways of failing to make the two languages work together, and we do not know which of those you have tried.
>If C++ and Fotran XE2011 are not in the same platform, Is that possible to link them together?
If the objects are for different OS or architecture targets, with rare exceptions they cannot be linked together.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Intel Visual Fortran includes example projects of Fortran calling C and C calling Fortran. The error message you indicate suggests that you added a !DEC$ ATTRIBUTES DLLIMPORT :: C directive but are linking to a static object file. Remove the ATTRIBUTES DLLIMPORT and see if that helps.
I do agree that learning how to use the C interoperability features would be useful.
I do agree that learning how to use the C interoperability features would be useful.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I believe Visual C++ 2008 express& XE2011 are the same architecture since I had no problem to use C/C++ procedureto call Frotran DLL created from XE2011.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You have, for some reason, added a private reply in which you posted example code from a book. I'm not sure why you did that. However, I took the Fortran and C code you supplied, compiled the Fortran with Intel Visual Fortran and the C code with Microsoft Visual C++, and they linked together fine.
One thing you might need to know is that Microsoft Visual C++ defaults to DLL linking whereas Intel Fortran defaults to static linking. You need to make sure that both compilations are done the same way. Please see this article for more information on mixed-language programming.
I suppose another possibility is that as you are using Visual C++ Express, the Fortran environment doesn't know how to find the MSVC libraries you are using. As you didn'ty show the error message, just the number (which tells me little), I can't comment further.
Please do not mark posts private unless they contain confidential information. Doing so greatly restricts the audience for your question.
[plain]C:Projects>cl -c /MT tc.c Microsoft 32-bit C/C++ Optimizing Compiler Version 16.00.40219.01 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. tc.c C:Projects>ifort tf.f90 tc.obj Intel Visual Fortran Compiler XE for applications running on IA-32, Version 1 2.1.1.258 Build 20111011 Copyright (C) 1985-2011 Intel Corporation. All rights reserved. Microsoft Incremental Linker Version 10.00.40219.01 Copyright (C) Microsoft Corporation. All rights reserved. -out:tf.exe -subsystem:console tf.obj tc.obj C:Projects>tf.exe 99 9.900000 2 3 4 doubling x 1.100000 2.200000 99 9.900000 1 2 3 4 5 6 [/plain]
One thing you might need to know is that Microsoft Visual C++ defaults to DLL linking whereas Intel Fortran defaults to static linking. You need to make sure that both compilations are done the same way. Please see this article for more information on mixed-language programming.
I suppose another possibility is that as you are using Visual C++ Express, the Fortran environment doesn't know how to find the MSVC libraries you are using. As you didn'ty show the error message, just the number (which tells me little), I can't comment further.
Please do not mark posts private unless they contain confidential information. Doing so greatly restricts the audience for your question.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Steve,
Many thanks, I followed your steps, and it was successful.
The reason I posted privately is I am not sure about copyright issue.
On'Building Intel@ Fortran/C Programs on Window* Systems', it states:
"If you are using another C compiler, you can edit your code within the integrated development environment. However, you must compile your code outside the integrated development environment and either build the Fortran/C program on the command line or add the compiled C .OBJ file to your Fortran project in the Microsoft IDE. "
It appears to me weCAN use Fortran IDE to build mixed Fortran/C. I would like to build this way since I have too many routines in Fortran,but I haven't managed.
Best Regards
Xianfa
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Xianfa,
If you have a Fortran main program calling C routines, it is pretty easy. Right click on your "solution" (not the project) and select Add > New Project... Under Visual C++ select Win32 > Win32 Project. Name the project. Note that it will tend to put it in a directory outside your current solution, you can change that if you wish. Click OK. When the project wizard comes up, click Next (not Finish). On the next page, select "Static Library" as the project type. You will probably want to clear the "Precompiled headers" box. Add your C source files to this project.
Next, right click on the Fortran project and select Project Dependencies. Check the box for the C project.
Last, make sure that C and Fortran are using the same runtime library type. In the C project this is under Code Generation, for Fortran it is Libraries.
Now when you build the solution, both projects will be built and linked together.
If you have a C main calling Fortran it is a bit more complicated, especially in VS2010. Let me know if you need that info.
If you have a Fortran main program calling C routines, it is pretty easy. Right click on your "solution" (not the project) and select Add > New Project... Under Visual C++ select Win32 > Win32 Project. Name the project. Note that it will tend to put it in a directory outside your current solution, you can change that if you wish. Click OK. When the project wizard comes up, click Next (not Finish). On the next page, select "Static Library" as the project type. You will probably want to clear the "Precompiled headers" box. Add your C source files to this project.
Next, right click on the Fortran project and select Project Dependencies. Check the box for the C project.
Last, make sure that C and Fortran are using the same runtime library type. In the C project this is under Code Generation, for Fortran it is Libraries.
Now when you build the solution, both projects will be built and linked together.
If you have a C main calling Fortran it is a bit more complicated, especially in VS2010. Let me know if you need that info.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Steve,
Many thanks, however,I'm using Intel XE 2011 with Video Studio Shell 2008. There is NO 'solution' button, and also Intel XE2011 and Microsoft Visual C++ 2008 express are not in the same platform.
Best Regards
Xianfa
Many thanks, however,I'm using Intel XE 2011 with Video Studio Shell 2008. There is NO 'solution' button, and also Intel XE2011 and Microsoft Visual C++ 2008 express are not in the same platform.
Best Regards
Xianfa
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In that case, you can't do it from the VS enviroinment. The best you can do is compile the C++ code separately and then add the .obj or .lib to your Fortran project as a source file.
There is not a "button" for solution, but it is the topmost item in the "Solution Browser" tree. However, with the separate VS Shell and VC Express environments, you can't use that option.
There is not a "button" for solution, but it is the topmost item in the "Solution Browser" tree. However, with the separate VS Shell and VC Express environments, you can't use that option.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Just a bit of an update on this. We (Xianfa and I) were able to successfully build and run mixed Fortran, C, and C++ code in the same Visual Studio 2010 solution. With this accomplished we were able to call a Windows Form from Fortran! Thanks a lot to Steve for the step-by-step guide. We had to play around a bit with getting the dependencies just right because we are using multiple projects. Also, to build and run in the command prompt for the release version, we had to use xilink instead of the normal Visual Studio link. Otherwise, everything worked using both the Intel C++ and Microsoft C++ compilers.
There are still some issues with trying to get this to work with a WPF library. It would seem that the /MT and /clr options are 'incompatible' for an unknown reason, likely something to do with how threading works. There may be a method of using dll's by some means. I will explore the possibilities as best as I can, but any advice is welcome.
There are still some issues with trying to get this to work with a WPF library. It would seem that the /MT and /clr options are 'incompatible' for an unknown reason, likely something to do with how threading works. There may be a method of using dll's by some means. I will explore the possibilities as best as I can, but any advice is welcome.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Another update: I've managed to get a window form with WPF controls on
it to come up now, all being originally called from our old non-standard
Fortran 77. I won't go into great details. You can google how to have a
windows form display WPF content. The real trick was that I had to
create a STA thread, and use a cross-thread call (Invoke) to assign my
WPF content to the child of an ElementHost, that was itself added to the
Controls of a UserControl. I then added all of this to the Controls
collection of the form successfully displayed in my previous post. Note that my UserControl was in its own project in its own solution, and is an assembly that is registered (using regasm). Also the WPF stuff is in its own project, actually using Visual Studio C# Express 2010.
I still have to sort out a few issues with focus, but this should solve our short term issues until we can overhaul our old Fortran and bring it into the modern era. :)
If anybody wants any of the gritty details on the WPF stuff, just let me know here. Thanks for all the help!
I still have to sort out a few issues with focus, but this should solve our short term issues until we can overhaul our old Fortran and bring it into the modern era. :)
If anybody wants any of the gritty details on the WPF stuff, just let me know here. Thanks for all the help!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Tom,
This is great - can you share a working example with us here? Attach a ZIP of the solution(s)/project(s) to a reply.
This is great - can you share a working example with us here? Attach a ZIP of the solution(s)/project(s) to a reply.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Does anybody know how to set a Fortran executable up to be a STA Thread? In C++, C#, etc... you normally just mark an attribute 'Main' entry point method.
To provide a little background: The current setup we have basically runs the Fortran code to that thread's extinction before allowing any of the WPF stuff (on its own thread likewise) to actually be called, or perhaps more acurately, respond to being called. Every attempt I've made to circumvent this has led to an exception: "The calling thread must be STA, because many UI components require this." This should be a final hurdle for us to truly integrate our code together (and me posting a simple example set of projects).
Update:
So I tried calling the Ole32 method CoInitialize and CoUninitialize directly:
use ole32
.
.
.
interface
subroutine CoInitialize(pvoid)
!DEC$ IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS:'_CoInitialize@4' :: CoInitialize
!DEC$ ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS: 'CoInitialize' :: CoInitialize
!DEC$ ENDIF
integer :: pvoid
end subroutine
end interface
interface
subroutine CoUninitialize( )
!DEC$ IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS:'_CoUninitialize@4' :: CoUninitialize
!DEC$ ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS: 'CoUninitialize' :: CoUninitialize
!DEC$ ENDIF
end subroutine
end interface
call CoInitialize(0) ! Works fine
.
.
.
call CoUninitialize()
! Linker error: Error 2 error LNK2019: unresolved external symbol _CoUninitialize@4 referenced in function _MAIN__ QWin1.obj
So I tried OleInitialize instead:
integer :: initVar
.
.
.
interface
integer function OleInitialize( reserved )
!DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS : "OleInitialize" :: OleInitialize
integer, intent(in) :: reserved
!DEC$ ATTRIBUTES VALUE :: reserved
end function OleInitialize
end interface
interface
subroutine OleUninitialize( )
!DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS : "OleUninitialize" :: OleUninitialize
end subroutine OleUninitialize
end interface
initVar = OleInitialize(0)
.
.
.
call OleUninitialize()
This 'worked' in that it compiled, linked and ran as usual, but I'm still getting an exception that I'm not calling my UI controls from a STA thread up in my forms control. Have I truly made the Fortran .exe a STA thread with these calls?
UPDATE:
The answer 'yes'. I will try to post some sample projects asap.
To provide a little background: The current setup we have basically runs the Fortran code to that thread's extinction before allowing any of the WPF stuff (on its own thread likewise) to actually be called, or perhaps more acurately, respond to being called. Every attempt I've made to circumvent this has led to an exception: "The calling thread must be STA, because many UI components require this." This should be a final hurdle for us to truly integrate our code together (and me posting a simple example set of projects).
Update:
So I tried calling the Ole32 method CoInitialize and CoUninitialize directly:
use ole32
.
.
.
interface
subroutine CoInitialize(pvoid)
!DEC$ IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS:'_CoInitialize@4' :: CoInitialize
!DEC$ ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS: 'CoInitialize' :: CoInitialize
!DEC$ ENDIF
integer :: pvoid
end subroutine
end interface
interface
subroutine CoUninitialize( )
!DEC$ IF DEFINED(_X86_)
!DEC$ ATTRIBUTES STDCALL, ALIAS:'_CoUninitialize@4' :: CoUninitialize
!DEC$ ELSE
!DEC$ ATTRIBUTES STDCALL, ALIAS: 'CoUninitialize' :: CoUninitialize
!DEC$ ENDIF
end subroutine
end interface
call CoInitialize(0) ! Works fine
.
.
.
call CoUninitialize()
! Linker error: Error 2 error LNK2019: unresolved external symbol _CoUninitialize@4 referenced in function _MAIN__ QWin1.obj
So I tried OleInitialize instead:
integer :: initVar
.
.
.
interface
integer function OleInitialize( reserved )
!DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS : "OleInitialize" :: OleInitialize
integer, intent(in) :: reserved
!DEC$ ATTRIBUTES VALUE :: reserved
end function OleInitialize
end interface
interface
subroutine OleUninitialize( )
!DEC$ ATTRIBUTES DEFAULT, STDCALL, DECORATE, ALIAS : "OleUninitialize" :: OleUninitialize
end subroutine OleUninitialize
end interface
initVar = OleInitialize(0)
.
.
.
call OleUninitialize()
This 'worked' in that it compiled, linked and ran as usual, but I'm still getting an exception that I'm not calling my UI controls from a STA thread up in my forms control. Have I truly made the Fortran .exe a STA thread with these calls?
UPDATE:
The answer 'yes'. I will try to post some sample projects asap.

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page