在Excel中通过vba加载dylib for mac

我正在尝试使用mac公开C ++ DLL到Excel。 DLL是用Xcode 4编写和编译的,而且我正在使用Excel 2011。

对于简单的函数,extern“C”做的工作,我可以在Excel中使用dylib。 具体来说,如果C ++代码是类似的

extern "C" { double sumC( double a, double b) { return a + b; } } 

和VBA代码是:

 Private Declare Function addFunction _ Lib "Macintosh HD:Users:SVM:Documents:Excel:lib:libTestDLLtoVBA.dylib" _ Alias "sumC" (ByVal a As Double, ByVal b As Double) As Double Function Addition(a As Double, b As Double) Addition = addFunction(a, b) End Function 

一切正常。 但是,我感兴趣的是将更复杂的代码暴露给头文件中定义的类,如下例所示 – 在这种情况下,Excel返回#VALUE !. 我的C ++代码是这样的

头文件:

 #ifndef TestDLLtoVBA_TestFunction_h #define TestDLLtoVBA_TestFunction_h class AdditionVBATest{ public: AdditionVBATest(){}; AdditionVBATest( double ){ m_AdditionResult = 0.0; } ~AdditionVBATest(){}; void setResult( double nAddition ){ m_AdditionResult = nAddition; } double getResult(){ return m_AdditionResult; } void addFunct( double x, double y, double &nResult ); double addFunct( double, double ); private: double m_AdditionResult; }; double addFunctionC( double a, double b); #endif 

cpp文件:

 #include <iostream> #include "TestFunction.h" void AdditionVBATest::addFunct(double x, double y, double &nResult) { nResult = 0.0; nResult = x + y; AdditionVBATest::setResult(nResult); } double AdditionVBATest::addFunct( double a, double b ) { double nResult(0.0); AdditionVBATest addCompute; addCompute.AdditionVBATest::addFunct(a, b, nResult); AdditionVBATest addResult; return addResult.getResult(); } 

最后,这是包含我想暴露给Excel的函数的文件:

 #include <iostream> #include "TestFunction.h" extern "C" { double addFunctionC( double a, double b) { AdditionVBATest *resAddition; double result(0.0); result = resAddition->AdditionVBATest::addFunct(a, b); return result; } } 

我试图在C ++应用程序中使用相同的dylib,并且工作正常,所以我相信这是通过VBA公开库的事情。

我使用的VBA代码是

 Private Declare Function addFunction _ Lib "Macintosh HD:Users:SVM:Documents:Excel:lib:libTestDLLtoVBA.dylib" Alias "addFunctionC" _ (ByVal a As Double, ByVal b As Double) As Double Function Addition(a As Double, b As Double) Addition = addFunction(a, b) End Function 

任何帮助将不胜感激。

这当然没有必要,但为了简化,我将从现在开始假设你的头文件和两个源文件都在同一个目录下,并且所有将来的命令都在这个目录下执行。 然后在两个源文件中replace

 #include "TestFunction.h" 

 #include "./TestFunction.h" 

然后,编译如下:

 g++ -m32 -Wall -g -c ./TestFunction.cpp -o ./TestFunction.o g++ -m32 -dynamiclib ./file.cpp ./TestFunction.o -o ./libTestDLLtoVBA.dylib 

哪里

  • g ++是你的 gcc。 我想这是铛的一个,在我的电脑上它是gcc 5.2.0,但都应该工作正常
  • file.cpp是包含addFunctionC声明的源文件
  • -m32选项要求产生一个32位dylib,因为在mac上的excel / VBA是32位

现在做一个nm -gU libTestDLLtoVBA.dylib ,你会看到一行_addFunctionC表明函数addFunctionC确实被导出。

在VBA中,声明如下:

 Declare Function addFunctionC Lib "/Path/to/your/libTestDLLtoVBA.dylib" (ByVal x As Double, ByVal y As Double) As Double Function Addition(a As Double, b As Double) Addition = addFunction(a, b) End Function 

它应该工作。 这是一个很大的灵感来源。

现在,如果你不想使用命令行,想要使用XCode,我只能说你唯一要做的就是确保XCode产生一个32位的dylib,就像excel / VBA是32位只在Mac OS X.我真的认为这32位的东西是你的问题。

您可能想要阅读COM自动化对象。 有时被称为“OLE”或“ActiveX”。 它本质上是一种将用C ++编写的类和对象公开给其他编程语言的方法。

对于脚本环境(VBA和Javascript),传统的方法是通过注册一个公开IDispatch接口的COM对象。

一些链接,让你开始:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms221375(v=vs.85).aspx

https://msdn.microsoft.com/en-us/library/windows/desktop/ms221326(v=vs.85).aspx

不要挂在“控制”和embedded式用户界面窗口的细节。 Foucs获得一个简单的COM对象类和接口声明在一个IDL中,生成一个typelib,实现一个C ++类,实现接口和IDispatch。 ATL(活动模板库)使这个东西容易。