大神好!快过年了还发帖求助,很是抱歉,提前给拜个年吧! 我用C#调用Fortran的dll,在各位大神指导下,终于成功了,但有些疑问,还请指点一下。 电脑配置是VS2013+IVF2013。由于Fortran输出的dll用到了其他的dll(IMSL库)和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+IVF2013,IMSL7.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 我属于非专业程序员,提问中很多不专业的地方,请谅解!
|