【发布时间】:2010-04-27 10:04:58
【问题描述】:
如何使用 gcc 编译器/Mingw for Visual Basic 创建 dll?
【问题讨论】:
-
什么 Visual Basic 版本?你想在VB中使用什么技术来调用dll:COM还是API调用/PInvoke?
如何使用 gcc 编译器/Mingw for Visual Basic 创建 dll?
【问题讨论】:
以下是我如何让 MinGW 构建用于 Excel 2003 VBA 的 DLL。
fooBar.cpp
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
生成的 fooBar.def 看起来像:
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-iquette:
所有导出的函数都应该有 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
现在您应该可以像 mmorris answer 一样调用 square_xxx 了。不过,他的解决方案可能有效。
【讨论】:
这个:http://www.mingw.org/wiki/DLL 可能对你有用。
【讨论】:
VB(所有版本)更喜欢帕斯卡调用约定。
使用 WINAPI 声明您的外部函数并将它们导出到您的 .def 文件中。
【讨论】: