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

How do I build a .lib file with my .dll using gfortran?

我需要使用 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。如果需要,我可以 post 其余代码。

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)/*

可以指示 gcc linker 输出模块定义文件(.def 扩展名),该文件描述了 DLL 的所有导出。

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

将您的 link 行更改为:

$(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)时需要特别小心。