如何使用gcc编译器/Mingw为Visual Basic创建dll?
int __stdcall Foo(int x)
{
return x * x;
}
double __stdcall Bar(double x)
{
return x * x;
}
1) 打开MinGW shell并创建一个名为fooBar
的目录。
关闭Excel工作簿(如果已打开)。
mkdir -p fooBar
cd fooBar
rm *.a *.dll *.def
2) 编译并生成一个 .def 文件 - 注意:这个 DLL 不会工作,因为它有混淆符号。
gcc -shared -o fooBar.dll fooBar.cpp -Wl,--output-def,fooBar.def,--out-implib,libfooBardll.a
EXPORTS
_Z3Bard@8 @1
_Z3Fooi@4 @2
3) 通过为生成的符号添加干净的符号别名修改生成的 fooBar.def 文件。现在,fooBar.def 应该看起来像这样:
EXPORTS
_Z3Bard@8 @1
_Z3Fooi@4 @2
Bar = _Z3Bard@8
Foo = _Z3Fooi@4
4) 再次清理(除了修改过的fooBar.def文件)
rm *.a *.dll
5) 使用带有干净符号别名的.def文件编译生成的符号。
gcc -shared -o fooBar.dll fooBar.cpp fooBar.def -Wl,--out-implib,libfooBar_dll.a
6) 打开 Excel 并添加以下 VBA 代码(确保使用正确的路径,路径中不应包含 mmorris):
Private Declare Function Foo Lib _
"C:\MinGW\msys\1.0\home\mmorris\fooBar\fooBar.dll" _
(ByVal x As Long) As Long
Private Declare Function Bar Lib _
"C:\MinGW\msys\1.0\home\mmorris\fooBar\fooBar.dll" _
(ByVal x As Double) As Double
7) 如果您想从Excel工作簿中调用函数,在单元格中输入=Foo(5)
或=Bar(5)
首先,关于DLL的规范:
所有导出函数都应该具有C语言链接。
在DLL内部抛出的所有C++异常都应该在DLL内部捕获。
为什么?因为Windows上没有标准的C++ ABI。
此外,在应该导出的函数上使用__declspec(dllexport)。
现在让我们来看如何制作不需要任何DEF文件的DLL。
fooBar.cpp
#ifdef __cplusplus
extern "C"
{
#endif
__declspec(dllexport) int __stdcall square_int(int x) //I prefer manual mangling in this case to support static polymorphism
{
return x * x;
}
__declspec(dllexport) double __stdcall square_double(double x)
{
return x * x;
}
#ifdef __cplusplus
}
#endif
使用编译
gcc fooBar.cpp -shared -Wl,--kill-at -o fooBar.dll
VB(所有版本)更喜欢使用Pascal调用约定。
使用WINAPI声明您的外部函数,并在您的.def文件中导出它们。