- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
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?
コピーされたリンク
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
cl /std:c++17 /c normal_array.cpp
ifort xnormal.f90 normal_array.obj
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Thanks @mecej4 , that works for me, but I would still like to know how to do it with the g++ compiler.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
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.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
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.
- 新着としてマーク
- ブックマーク
- 購読
- ミュート
- RSS フィードを購読する
- ハイライト
- 印刷
- 不適切なコンテンツを報告
Yes, isolating one or the other in a DLL is a good way to avoid some of these incompatibilities.
