通过vba for mac在Excel中加载dylib

时间:2015-01-24 20:41:48

标签: c++ excel macos vba excel-vba

我正在尝试使用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更复杂的代码 - 如下例所示 - 在这种情况下,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

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

这当然不是必需的,但为了简化,我将从现在开始假设您的头文件和两个源文件在同一目录中,并且所有将来的命令都在此目录中执行。然后替换两个源文件

#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

它应该有效。 This是灵感的重要来源。

现在,如果您不想使用命令行并希望使用XCode,我会说您唯一要注意的是确保XCode产生32位dylib,如excel / VBA仅在Mac OS X上是32位。我真的认为这32位是你的问题。

答案 1 :(得分:-1)

您可能想要阅读COM自动化对象。有时被称为&#34; OLE&#34;或&#34; ActiveX&#34;。它本质上是一种将用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

不要挂断&#34;控制&#34;的细节。和嵌入式UI窗口。获取在IDL中声明的简单COM对象类和接口,生成类型库,实现实现接口和IDispatch的C ++类。 ATL(活动模板库)使这个东西变得简单。