我正在尝试使用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
非常感谢任何帮助。
答案 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
,其中
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(活动模板库)使这个东西变得简单。