- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For normal_array.cpp
// https://people.duke.edu/~ccc14/sta-663-2018/notebooks/S12_CPP_Annotated.html
#include <random>
#include <functional> // needed for bind
extern "C" void normal_vec(int seed, int n, double x[]);
using std::default_random_engine,std::normal_distribution, std::bind;
void normal_vec(int seed, int n, double x[]) {
// start random number engine with fixed seed
default_random_engine re{seed};
normal_distribution<double> norm(0,1); // mean and standard deviation
auto rnorm = bind(norm, re);
for (int i = 0; i<n; ++i) x[i] = rnorm();
}
and xnormal.f90
program random_normal
use iso_c_binding
implicit none
!
interface
subroutine normal_vec(seed, n, x) bind(c)
import c_int, c_double
integer(kind=c_int), intent(in), value :: seed, n
real(kind=c_double) :: x(n)
end subroutine normal_vec
end interface
!
integer :: seed
integer, parameter :: n = 5
real(kind=c_double) :: x(n)
!
do seed=1,3
call normal_vec(seed,n,x)
print "(*(1x,f7.4))",x
end do
end program random_normal
I can compile and link on WSL2 with
g++ -c normal_array.cpp
ifort -c -o xnormal.o xnormal.f90
ifort normal_array.o xnormal.o
Trying that on Windows gives
normal_array.o : fatal error LNK1143: invalid or corrupt file: no symbol for COMDAT section 0x5
How should I compile and link on Windows?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
cl /std:c++17 /c normal_array.cpp
ifort xnormal.f90 normal_array.obj
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks @mecej4 , that works for me, but I would still like to know how to do it with the g++ compiler.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
As Steve wrote, in general mixing objects from different compilers (in fact, compilers from different stables) will not work, because Ifort compiled objects will have dependencies on MS C/C++ libraries, and G++ compiled objects will depend on GNU libraries, with a lot of duplicated entry points between the two sets.
In this rather simple example, there is only one entry point needed, and the following steps worked when I used Cygwin G++.
g++ -shared -fPIC normal_array.cpp -o normal_array.dll
lib /def:normal_array.def /machine:x64
ifort xnormal.f90 normal_array.lib
where normal_array.def contains
LIBRARY NORMAL_ARRAY.DLL
EXPORTS
normal_vec
You can reduce the size of the DLL by adding the option -s to the g++ command line.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It may not be possible. You'd end up with a mix of g++ and MSVC library code in there, and bad things might happen.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, isolating one or the other in a DLL is a good way to avoid some of these incompatibilities.

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