Fortran Coder

查看: 8665|回复: 4
打印 上一主题 下一主题

[混编] C#调用Fortran的dll疑问

[复制链接]

58

帖子

9

主题

0

精华

熟手

F 币
256 元
贡献
163 点
跳转到指定楼层
楼主
发表于 2017-1-25 19:28:04 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
大神好!快过年了还发帖求助,很是抱歉,提前给拜个年吧!
我用C#调用Fortrandll,在各位大神指导下,终于成功了,但有些疑问,还请指点一下。
电脑配置是VS2013+IVF2013。由于Fortran输出的dll用到了其他的dllIMSL库)和waspcn.dll等,我先定义dll的称呼:Fortran输出给C#直接使用的dll称为dll()dll()引用的dll称为dll(子)。
我对动态链接的理解是:只建立一个引用的接口,而真正的代码和数据存放在另外的可执行模块中,在运行时再装入。
我的第一个问题是:
只要保证dll()在生成导出时无误,且其用到的dll(子)及其相关的dll放在Fortran中的DEBUG/RELEASE目录下就可以了。而不需要把dll(子)及其相关的dll复制到C#中的debug下(C#EXE文件的目录)。在C#调用dll(父)时会在上述目录中自动搜寻dll(子)及其相关的dll,是不是这样呢?还是需要把dll(子)及其相关的dll也要复制到C#中的debug下(C#EXE文件的目录),C#调用dll(父)时才能找到?
第二个问题是:
周老师的教材说,Windows搜索要装入的DLL的顺序
1. 应用程序所在的路径
2. 当前工作目录
3. Windows SYSTEM目录。通过调用GetSystemDirectory函数可以获取这个目录的路径。
4. 16位系统的目录。并没有函数可以获取这个目录的路径,但是它会被查找。
5. Windows目录。通过调用GetWindowsDirectory函数可以获取这个目录的路径。
6. PATH环境变量指定的路径。
上述是dll()生成导出时搜寻dll(子)及其相关的dll的顺序还是C#调用dll(父)时搜寻dll(父)的顺序?如果不是前者的顺序,那搜寻的顺序有应该是什么?如果是前者,dll()生成导出时并没有应用程序,同时工作目录又指的那个目录(难道是Fortran工程中的debug文件目录)?
我理解是后者的搜寻顺序,应用程序为C#debug下目录(C#EXE文件的目录),当前工作目录为C#属性中设置的工作目录,一般设置为dll(父)位置对应的目录。
第三个问题是:
我在联想笔记本上生成的dll(父)且能正常调用,换到戴尔笔记本上也能正常调用,但是如果在戴尔笔记本上重新生成dll时,就会出错,如下图所示。我换到戴尔笔记本时把整个解决方案的文件夹都复制过去了,waspcn.dll也在解决方案对应的DEBUG/RELEASE文件夹内。
两台笔记本电脑都是英特尔的处理器,64位操作系统,VS2013+IVF2013IMSL7.0(都已经设置好路径),也都把redist的目录设置了path环境变量。这让我百思不得其解。
第四个问题是:
把程序打包制作成windows安装程序时会自动把所需的所有dll(子)及其相关的dll都会复制吧?要不然换一台电脑又用不了。我已经在联想/戴尔笔记本电脑上把redist的目录设置了path环境变量。
同时,我用到了IMSL库,但是没有用MKL库,用depends分析时总提示mkl的一些链接库找不到。也是很纳闷。
第五个问题是:
Fortran工程中导出dll()时,如果有部分dll(子)找不到,系统不会提示?而非得让depends来分析才能找出来,这算是微软VS的一个bug吗?
第六个问题:
我在教材上看到:”动态库一般会有对应的导入库,方便程序静态载入动态链接库,否则可能就需要自己LoadLibrary调入DLL文件,然后再手工GetProcAddress获得对应函数了。有了导入库,只需要链接导入库后按照头文件函数接口的声明调用函数就可以了。“
但是我在C#项目中没有添加导入库,也能正常使用。后来得知C#不需要导入库,通过DLLImport命令就可以直接调入dll文件。
那哪种语言调用dll时需要使用lib文件,c/c++Fortran,还是与输出dll的语言有关,我现在是云里雾里的,请指点迷津。
d
我属于非专业程序员,提问中很多不专业的地方,请谅解!

错误图片一.png (16.93 KB, 下载次数: 226)

错误图片一.png

错误图片2.png (16.72 KB, 下载次数: 253)

错误图片2.png
分享到:  微信微信
收藏收藏 点赞点赞 点踩点踩

954

帖子

0

主题

0

精华

大师

F 币
184 元
贡献
75 点

规矩勋章元老勋章新人勋章水王勋章热心勋章

QQ
沙发
发表于 2017-1-26 11:00:56 | 只看该作者

回帖奖励 +20

第一个问题:
Windows加载C#的exe时,就会加载所有使用到的dll(父)及dll(子)
加载时,不区分父子。因此,他们的加载规则是一样的。

第二个问题:
周振红教材里说的加载顺序并不完整。
其中缺少了 WinSxS , .Net framework , KnownDLLs 等(当然这些不太重要)
这个顺序是加载DLL的顺序(不区分父子,参考第一个问题)

第三个问题:
fortcom 是 IVF 的一部分,它遇到了权限问题。
这个比较难说,你可以试试用管理员身份运行VS。如果依然有问题,可能是磁盘错误,导致IVF目录的NTFS权限信息丢失。尝试一下 chkdsk /f
(这几乎不是fortran问题)

第四个问题:
会不会自动把所需的dll打包,取决于你的打包方式。
windows installer ? 还是 Wise ?InstallShielden?或者 NSIS ?
一般来说,需要自己写脚本(或配置)哪些文件需要打包。
推荐的方式是把所有所需的DLL(不区分父子)全部打包给用户。
实际上,你可以在很多常用的软件目录里找到很多编译器的运行时库,例如 borlandmm.dll msvcrt.dll 等等

第五个问题:
你说的导出dll是什么意思?
编译器在编译时,并不会检查所需的dll是否存在,只有运行时由windows检查。
depends(或同类软件)可以检查出来静态依赖的DLL(对于动态依赖的DLL也无法检查)
这不算是bug
MKL的一部分DLL就属于动态依赖的(由Loadlibrary动态加载)

第六个问题:
导入库一般VC++才需要。fortran也可以用导入库。
这与dll的使用者有关(而不是dll的提供者)
事实上,没有导入库也没关系~~只要知道函数的接口(函数的定义),完全可以自己写一个只有接口,但没有内部实现的代码,编译之后,得到的导入库,与真实的导入库一样。

c# 的 DLLImport 实际上完成的,也是导入库的作用:“即:告知编译器函数的定义”
c#是托管代码,所有DLL都是动态加载的。

58

帖子

9

主题

0

精华

熟手

F 币
256 元
贡献
163 点
板凳
 楼主| 发表于 2017-2-1 13:07:23 | 只看该作者
vvt 发表于 2017-1-26 11:00
第一个问题:
Windows加载C#的exe时,就会加载所有使用到的dll(父)及dll(子)
加载时,不区分父子。因此 ...

感谢VVT的及时回复,祝您新春快乐!

学习了您的指导,受益匪浅!
可能是我提问中表达得不够清楚,部分回答不是我想了解的。
第一个问题中:我想确认的是“只要保证dll(父)在生成导出时无误,且其用到的dll(子)及其相关的dll放在Fortran中的DEBUG/RELEASE目录下就可以了。而不需要把dll(子)及其相关的dll复制到C#中的debug下(C#中EXE文件的目录)。”,是这样的吗?

第二个问题中:我想知道的是“周老师的教材说,Windows搜索要装入的DLL的顺序是dll(父)生成导出时搜寻dll(子)及其相关的dll的顺序还是C#调用dll(父)时搜寻dll(父)的顺序,或者都是?

第四个问题中:我用到了IMSL库,但是没有用MKL库,用depends分析时总提示mkl的一些链接库找不到。这难道是这两个函数库之间的有关联?

954

帖子

0

主题

0

精华

大师

F 币
184 元
贡献
75 点

规矩勋章元老勋章新人勋章水王勋章热心勋章

QQ
地板
发表于 2017-2-1 14:00:56 | 只看该作者
本帖最后由 vvt 于 2017-2-1 14:07 编辑

第一个问题,我已明确你想了解的是什么。所以我告诉你“不区分父子”,凡是使用到的 DLL(不管是父还是子)
都必须在“windows搜索DLL的搜索范围内”(搜索范围参考后面的问题)
也就是说,exe依赖dll(父),dll(父)再依赖dll(子)。与
exe直接依赖dll(子)
是一样的。windows都认为所有的dll,都是exe所依赖的。这些 dll 必须都被windows搜索到,才能正常使用这个 exe
(debug文件夹或release文件夹,是exe所在路径,也是windows搜索范围的其中之一,也是最常用的dll存放地点)

第二个问题:装入 dll 是 windows 的事情,不是 c# 的事情。

第四个问题:可能 IMSL 后端又用到了 MKL。很多函数库都是有下一层的依赖的。

58

帖子

9

主题

0

精华

熟手

F 币
256 元
贡献
163 点
5#
 楼主| 发表于 2017-2-1 15:29:41 | 只看该作者
vvt 发表于 2017-2-1 14:00
第一个问题,我已明确你想了解的是什么。所以我告诉你“不区分父子”,凡是使用到的 DLL(不管是父还是子) ...

感谢VVT的及时回复,再次感谢!
一开始我没能理解您的回复,不好意思,

您需要登录后才可以回帖 登录 | 极速注册

本版积分规则

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

GMT+8, 2024-4-26 14:15

Powered by Tencent X3.4

© 2013-2024 Tencent

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