不能从const char *转换为LPCWSTR问题,可以使用TEXT函数解决,参考:
https://www.cnblogs.com/dongsheng/p/3586418.html
C++代码
#include <iostream>
#include <Windows.h>
#include <stdio.h>
#include <float.h>
#include <stdlib.h>
typedef void(*LPFNDLLFUNC1)(char *c, const int len);
typedef int(*LPFNDLLFUNC2)(int input);
typedef float(*LPFNDLLFUNC3)(float input);
// 只要有一个定义成传址,其它所有参数都得设定成传址。可能跟DLL机制有关系?
typedef float(*LPFNDLLFUNC4)(int* length, float* input);
typedef float(*LPFNDLLFUNC5)(float* input, int* length, float* q);
typedef int(*LPFNDLLFUNC6)(float* input, int* row, int* col);
using namespace std;
int main(int argc, char** argv) {
printf("double MAX=%le, MIN=%le\n", DBL_MAX, DBL_MIN);
printf("float MAX=%le, MIN=%le\n", FLT_MAX, FLT_MIN);
const int lenmax = 30, numstr = 3; // changed char length to 30 to fit in the terminal
char a[numstr][lenmax];
string str[numstr];
str[0] = "moon";
str[1] = "mercury";
str[2] = "jupiter";
for (int k = 0; k < numstr; k++) {
memset(a[k], ' ', lenmax); // fill space
int i = 0;
for (; i < str[k].length();i++) {
a[k][i] = str[k][i];
}
cout << a[k] << endl;
}
HINSTANCE hDLL = LoadLibrary(TEXT("fortranDLLExample.dll")); // 使用这种调入DLL的方法,在链接器上不需要特殊处理。
if (hDLL == NULL){
cout << "Failed to load library.\n";
}else{
LPFNDLLFUNC1 lpfnDllFunc1; // Function pointer
lpfnDllFunc1 = (LPFNDLLFUNC1)GetProcAddress(hDLL, "func01");
lpfnDllFunc1(a[0], lenmax);
LPFNDLLFUNC2 ABZERO; // Function pointer
ABZERO = (LPFNDLLFUNC2)GetProcAddress(hDLL, "ABZERO");
int a=704; // fortran里面的类型一定要搞对!!!是interger(type=4)或者默认type,对应cpp里面的int
cout<<"ABZERO(704)=="<<ABZERO(a)<<endl;
LPFNDLLFUNC3 ABZERO_FLOAT; // Function pointer
ABZERO_FLOAT = (LPFNDLLFUNC3)GetProcAddress(hDLL, "ABZERO_FLOAT");
float b=500.0; // fortran里面的类型一定要搞对!!!是real,对应cpp里面的float,而不是double
cout<<"ABZERO_FLOAT(500.0)=="<<ABZERO_FLOAT(b)<<endl;
LPFNDLLFUNC4 sum; // Function pointer
sum = (LPFNDLLFUNC4) GetProcAddress(hDLL, "sum");
float c[]={11.0, 44.55, 66.44, 43.23, 6.32, 88.43};
int l = sizeof(c) / sizeof(c[0]);
cout<<"length=="<<l<<"; sum(500.0)=="<<sum(&l, c)<<endl;
LPFNDLLFUNC5 sum2; // Function pointer
sum2 = (LPFNDLLFUNC5) GetProcAddress(hDLL, "SUMANDTIMES");
float cc[]={11.0, 44.55, 6.32, 88.43};
l = sizeof(cc) / sizeof(cc[0]);
float q1 = 10.2;
cout<<"length=="<<l<<"; SUMANDTIMES([11.0, 44.55, 6.32, 88.43])=="<<sum2(cc, &l, &q1)<<endl;
LPFNDLLFUNC6 array2by2; // Function pointer
array2by2 = (LPFNDLLFUNC6) GetProcAddress(hDLL, "array2by2");
float ccc[]={1.1, 1.2, 1.3, 1.4,
2.1, 2.2, 2.3, 2.4,
3.1, 3.2, 3.3, 3.4,
4.1, 4.2, 4.3, 4.4};
int row, col;
row = 4;
col = 4;
cout<<"length=="<<l<<"; array2by2([11.0, 44.55, 6.32, 88.43])=="<<array2by2(ccc, &row, &col)<<endl;
}
FreeLibrary(hDLL);
return 0;
}
fortran代码如下:
! fortranDLLExample.f90
!
! FUNCTIONS/SUBROUTINES exported from fortranDLLExample.dll:
! fortranDLLExample - subroutine
FUNCTION ABZERO(P) bind(C,name="ABZERO")
!DEC$ ATTRIBUTES DLLEXPORT :: ABZERO
!DEC$ ATTRIBUTES VALUE :: P
integer, INTENT(IN) :: P
integer :: ABZERO
integer :: result1
! Examle calculation
result1 = P - 273
print *, "The p==", P, ";"
print *, "The p-273 [", result1, "]"
ABZERO = result1
RETURN
END FUNCTION
FUNCTION ABZERO_FLOAT(P) bind(C,name="ABZERO_FLOAT")
!DEC$ ATTRIBUTES DLLEXPORT :: ABZERO_FLOAT
!DEC$ ATTRIBUTES VALUE :: P
real, INTENT(IN) :: P
real :: ABZERO_FLOAT
real :: result1
! Examle calculation
result1 = P - 273.15
print *, "The p==", P, ";"
print *, "The p-273 [", result1, "]"
ABZERO_FLOAT = P - 273.15
RETURN
END FUNCTION
FUNCTION sum(length1, P) bind(C,name="sum")
!DEC$ ATTRIBUTES DLLEXPORT :: sum
implicit none
integer::length1
real, dimension(*):: P
real :: sum
integer::i
print *, "The length1==", length1, ";"
sum =0.0
do i = 1,length1 ! sum the array elements
sum = sum + p(i)
PRINT *,p(i)
end do
RETURN
END FUNCTION
subroutine func01( a ) bind(C,name="func01")
!DEC$ ATTRIBUTES DLLEXPORT :: func01
implicit none
character(len=1), dimension(90) , intent(in) :: a
character(len=30), dimension(3) :: b
integer*4 :: count,i,j
count=1
do j=1,3
b(J)=''
do I=1,30
b(J)=trim(b(J))//a(count)
count=count+1
enddo
enddo
print *
print *, "char length = ", len(b(1)), len(b(2)), len(b(3))
print *, "raw a(1) : [", b(1), "]"
print *, "raw a(2) : [", b(2), "]"
print *, "raw a(3) : [", b(3), "]"
print *, "trim : [", trim(b(1)), "] [", trim(b(2)), "] [", trim(b(3)), "]"
end
FUNCTION SUMANDTIMES(P, length1, Q) bind(C,name="SUMANDTIMES")
!DEC$ ATTRIBUTES DLLEXPORT :: SUMANDTIMES
implicit none
integer::length1
real, dimension(*):: P
real :: SUMANDTIMES, Q
integer::i
print *, "The length1==", length1, ";"
SUMANDTIMES =0.0
do i = 1,length1 ! sum the array elements
SUMANDTIMES = SUMANDTIMES + p(i) * Q
PRINT *,p(i)
end do
RETURN
END FUNCTION
FUNCTION array2by2(P, row, col) bind(C,name="array2by2")
!DEC$ ATTRIBUTES DLLEXPORT :: array2by2
USE ISO_C_BINDING
implicit none
integer::row, col, i, j, array2by2
!real,DIMENSION(row*col)::
real P(*)
real PP(row, col)
print *, "---->row-----", row
print *, "---->col-----", col
do i=1,row
do j=1,col
PP(i,j) = P((i-1)*row+j)
P((i-1)*row+j) = PP(i,j) * 100
print *, PP(i,j), i, j, (i-1)*row+j
end do
print *, "----row-----", i
end do
array2by2 = 0
RETURN
END FUNCTION