Fortran Coder

查看: 12233|回复: 8
打印 上一主题 下一主题

[混编] c++向Fortran编写的dll中传递字符串变成乱码

[复制链接]

1963

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1357 元
贡献
574 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

楼主
发表于 2016-11-3 11:22:54 | 显示全部楼层
最重要的错误是,filename 必须是 REFERENCE 的(传址),因为 stdcall 默认是传值
但是由于 REFERENCE 的不能用假定长度(*),所以一般会要求传递一个表示字符串长度的量:

[Fortran] 纯文本查看 复制代码
subroutine vlhm_forecast(filename,lens)
!DEC$ ATTRIBUTES STDCALL,DLLEXPORT::vlhm_forecast
!DEC$ ATTRIBUTES REFERENCE :: filename
character(len=lens)::filename            !c++主程序中传递进来的“Inputfile”变量
integer lens
write(*,*)"dll in filename is:"
write(*,*)filename
end subroutine

[C++] 纯文本查看 复制代码
extern "C" {void _stdcall   vlhm_forecast(char *,int); }
int _tmain(int argc, _TCHAR* argv[])
{
  char *inputfile = "C:\\Users\\www\\Desktop\\model_2\\cpp_main\\31005700.tem";
  printf("before calling:\n");
  printf("filename=\"%s\"", inputfile);
  printf("\n");
  vlhm_forecast(inputfile,strlen(inputfile));
  return 0;
}


1963

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1357 元
贡献
574 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

沙发
发表于 2016-11-3 11:32:09 | 显示全部楼层
在这个过程中,你用到了很多不规范的用法。只能在 IVF 编译器上使用。

更规范的用法是,使用 ISO_C_Binding。它与上面的区别是,使用了 C 的调用协定(而不是 stdcall)

[Fortran] 纯文本查看 复制代码
subroutine vlhm_forecast( pfilename , lens ) Bind(C,Name="vlhm_forecast")
!DEC$ ATTRIBUTES DLLEXPORT :: vlhm_forecast
  use , Intrinsic :: ISO_C_Binding
  type(C_PTR) , value :: pfilename !c++主程序中传递进来的“Inputfile”变量,是C语言的指针
  integer , value :: lens  
  character(len=lens) , pointer :: filename     !这是fortran的字符串       
  call c_f_pointer( pfilename , filename ) !//把 c 语言的指针转换成fortran字符串
  write(*,*)"dll in filename is:"
  write(*,*)filename
end subroutine

[C++] 纯文本查看 复制代码
extern "C" {void vlhm_forecast(char *,int); }
int _tmain(int argc, _TCHAR* argv[])
{
  char *inputfile = "C:\\Users\\www\\Desktop\\model_2\\cpp_main\\31005700.tem";
  printf("before calling:\n");
  printf("filename=\"%s\"", inputfile);
  printf("\n");
  vlhm_forecast(inputfile,strlen(inputfile));
  return 0;
}

这样做的好处是,fortran代码可以不做任何修改的在 linux gcc (或其他平台)上编译。

1963

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1357 元
贡献
574 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

板凳
发表于 2016-11-17 09:00:24 | 显示全部楼层
int main(){
就可以了。毕竟你只是测试。

1963

帖子

12

主题

5

精华

论坛跑堂

臭石头雪球

F 币
1357 元
贡献
574 点

美女勋章热心勋章星光勋章新人勋章贡献勋章管理勋章帅哥勋章爱心勋章规矩勋章元老勋章水王勋章

地板
发表于 2016-11-17 18:51:55 | 显示全部楼层
我的意思是改成
int main()
去掉里面的参数

我对 VC++ 懂得不多,抱歉。
您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

捐赠本站|Archiver|关于我们 About Us|小黑屋|Fcode ( 京ICP备18005632-2号 )

GMT+8, 2024-5-8 05:57

Powered by Tencent X3.4

© 2013-2024 Tencent

快速回复 返回顶部 返回列表