我想做标题所说的。之前已经讨论过这个问题(How to create dll using gcc compiler/Mingw for visual basic?),但这些帖子已有 10 年历史。那时我正在毫无困难地编写 Excel/VBA 宏,但现在我想将它们更新到 64 位 Windows。从那时起,我也切换了编译器。gcc使用orgfortran调用的DLL 创建 DLL 时我没有遇到任何gcc问题Python。很难理解兼容性问题,因为你不知道一篇文章是什么时候写的,也不知道它在 64 位世界中是否仍然有效。你可能会因为我重新讨论这个老话题而责备我,但也许其他人也有类似的问题。我还找到了一篇很棒的文章(https://www.transmissionzero.co.uk/computing/building-dlls-with-mingw/)。我已尝试遵循这两种方法,但无法在 Excel 电子表格中进行任何操作。也许我犯了一个对某人来说很明显的错误。这是函数,code.c:
__declspec(dllexport) int __stdcall sqint(int x){
return x * x;
}
我使用以下方法构建 DLL:
gcc code.c -shared -o code.dll -s -Wl,--subsystem,windows,--kill-at,-Map=code.map
code.map 文件和 objdump 实用程序都显示了函数,例如这里有几行来自objdump -p code.dll:
[Ordinal/Name Pointer] Table
[ 0] sqfloat
[ 1] sqint
哪里sqfloat是一个类似的双打代码。地图文件还显示了对库的引用,例如:
/usr/lib/gcc/x86_64-pc-cygwin/7.4.0/../../../../lib/libcygwin.a
接下来,我在 VBA 中声明它:
Declare PtrSafe Function sqint Lib "C:\Cwin\mix\code.dll" (ByVal x As Long) As Long
Visual Basic long 和 gcc int 都应该是 4 个字节。我应该可以直接调用该函数,但我尝试在调试期间将其放入另一个函数中。使用 VBA 调试器,我可以看到传递给函数的值,但除了可怕的#VALUE!. 如果您看到我做错了什么,我会很高兴收到您的来信。
2020 年 7 月 2 日更新:我再次尝试解决这个问题,但成功有限。我相信我创建的 DLL 不是 64 位的。我认为这将是默认设置。构建现在是这样的:
gcc code.c -Wa,-march=generic64 -shared -o code.dll -s -Wl,--subsystem,windows,--kill-at,-Map=code.map
在如何测试 DLL的帖子之后,使用file code.dll给出:
code.dll: PE32+ executable (DLL) (GUI) x86-64 (stripped to external PDB), for MS Windows
sqfloat 函数现在返回正确的结果,但最终 Excel 会出错并关闭。sqint 函数返回 2*2 = 1。我尝试使用Integer而不是long,但没有变化。MSVBA 是否改变了 long 的定义?
所以目前的状态是我偶尔会得到一个结果,但是宏会杀死 Excel。