如何使用gfortran使用我的.dll构建.lib文件?

时间:2016-10-10 13:38:30

标签: c++ visual-studio dll fortran msys2

我需要使用gfortran在Windows上构建FORTRAN DLL,以便C ++可以使用Visual Studio 2013调用它。

我已经使用MSYS2构建了一个示例DLL,但我无法弄清楚如何获取Visual Studio的LIB文件。

在线搜索主要产生了有关如何使用Visual Studio创建LIB文件的结果,以及如何仅从DLL和头文件创建LIB文件。但是我不想做后者涉及的讨厌的事情,我认为我不需要,因为我是构建DLL的人。我只想构建DLL并使用它获取我的LIB文件。

一个例外是this SO question,但答案对我来说并不清楚。看起来他已经做了类似于我已经找到的在DLL已经存在之后创建LIB文件的其他解决方案......但我无法相信这是最佳解决方案。

我不满意创建它的部分原因是我想把它放到一个进程中,以便其他开发人员可以在我之后使用代码 - 它不仅仅是一次性构建的东西。我不想给他们一份复杂的指示清单。

你知道怎么做或有任何关于如何去做的建议吗?

这是我写得不好的示例Makefile。如果需要,我可以发布剩下的代码。

Makefile: (我的编辑器用空格替换了标签)

FC=gfortran -g
CC=g++ -g

DLL_SRC_DIR=.
BUILD_DIR=build

all:
    $(FC) -c $(DLL_SRC_DIR)/fdll.f90 -o $(BUILD_DIR)/fdll.o

    $(CC) -c -DBUILDING_C_DLL $(DLL_SRC_DIR)/cdll.cpp -o $(BUILD_DIR)/cdll.o
    $(CC) -shared -o $(BUILD_DIR)/cdll.dll $(BUILD_DIR)/cdll.o $(BUILD_DIR)/fdll.o -Wl,--out-implib,$(BUILD_DIR)/libcdll.a -lgfortran

clean:
    rm -f $(BUILD_DIR)/*

编辑:感谢IanH,这是我的新Makefile!

FC=gfortran -g
CC=g++ -g

DLL_SRC_DIR=.
BUILD_DIR=build

all:
    $(FC) -c $(DLL_SRC_DIR)/fdll.f90 -o $(BUILD_DIR)/fdll.o

    $(CC) -c -DBUILDING_C_DLL $(DLL_SRC_DIR)/cdll.cpp -o $(BUILD_DIR)/cdll.o
    $(CC) -shared -o $(BUILD_DIR)/libcdll.dll $(BUILD_DIR)/cdll.o $(BUILD_DIR)/fdll.o -Wl,--out-implib,$(BUILD_DIR)/libcdll.a,--output-def,$(BUILD_DIR)/libcdll.def -lgfortran
    /c/Program\ Files\ \(x86\)/Microsoft\ Visual\ Studio\ 12.0/VC/BIN/lib /MACHINE:x86 /DEF:$(BUILD_DIR)\\libcdll.def /OUT:$(BUILD_DIR)\\libcdll.lib

clean:
    rm -f $(BUILD_DIR)/*

1 个答案:

答案 0 :(得分:2)

可以指示gcc链接器输出描述DLL中所有导出的模块定义文件(.def扩展名)。

然后,可以通过Microsoft库管理器将此def文件转换为导入库(.lib文件的形式),然后其他面向Windows的工具可以使用该静态库。

将您的链接更改为:

$(CC) -shared -o $(BUILD_DIR)/cdll.dll $(BUILD_DIR)/cdll.o \
    $(BUILD_DIR)/fdll.o \
    -Wl,--out-implib,$(BUILD_DIR)/libcdll.a,--output-def,$(BUILD_DIR)/libcdll.def \
    -lgfortran

并添加一个新行以生成静态库,例如:

LIB.EXE /MACHINE:x64 /DEF:$(BUILD_DIR)\libcdll.def /OUT:$(BUILD_DIR)\libcdll.lib

如果您没有编译x64,请将x64更改为适当的计算机类型。如果BUILD_DIR包含空格或类似内容,则会出现混淆。

然后可以将静态库提供给cl.exe Microsoft编译器驱动程序的调用。

请注意,在使用一个进程中具有不同运行时库的可执行模块(DLL&#,; EXE&#)时,需要特别小心。