我需要用C++编写一个DLL,其中包含一些稍后在VBA中使用的函数。为什么我的VBA没有在C++ DLL中找到函数?
我写这个样子的(不过,我承认我一直在从互联网上的一些例子复制,因为我很新到C++,我不知道我需要 .h文件所有这些东西):
// FieldTrans.h
#ifndef FIELDTRANS
#ifdef _WIN32
#ifdef BUILD_DLL
#define FIELDTRANS_FUNC __declspec(dllexport)
#else
#define FIELDTRANS_FUNC __declspec(dllimport)
#endif
#define FIELDTRANS_FUNC
#else
#define FIELDTRANS_FUNC __attribute__ ((visibility("default"))) type
#endif
// Returns the interpolated field matrix: 180° x 360° with Res step
FIELDTRANS_FUNC double ShannonInterp(double* Matrix, double Res, double DeltaTheta, double DeltaPhi);
// Returns the normalized cardinal sinus coefficient
FIELDTRANS_FUNC double SpecialLog(double x);
#endif
虽然.cpp文件中包含这些功能的实际定义:
// FieldTrans.cpp
#include "stdafx.h"
#include "FieldTrans.h"
#include <array> // for counting elements of an array
#define _USE_MATH_DEFINES // for M_PI
#include <math.h> // for M_PI and Log10
using namespace std;
double SinC(double x)
{
if (x == 0)
{
return 1;
}
else
{
return sin(M_PI * x)/(M_PI * x);
}
}
double ShannonInterp(double *Matrix[], double Res, double DeltaTheta, double DeltaPhi)
{
int k, l, m, n;
double iRes, jRes;
double ThetaSinC, PhiSinC;
int MatrixHeigth = sizeof(Matrix)/sizeof(Matrix[0]), MatrixWidth = sizeof(Matrix[0])/sizeof(Matrix);
int Height = 180/Res, Width = 360/Res;
double *Interpolated = new double[Height * Width];
k = 0;
m = 1;
for (int i = 0; i < Height; i++)
{
iRes = i * Res;
do
{
k = k + 1;
m = k + 1;
} while (iRes > (k + 1) * DeltaTheta);
if (m > MatrixHeigth)
{
m = MatrixHeigth - 1;
}
ThetaSinC = SinC((iRes - k * DeltaTheta)/DeltaTheta);
l = 0;
n = 1;
for (int j = 0; j < Width; j++)
{
jRes = j * Res;
do
{
l = l + 1;
n = l + 1;
} while (jRes > (l + 1) * DeltaPhi);
if (n > MatrixWidth)
{
n = 0;
}
PhiSinC = SinC((jRes - l * DeltaPhi)/DeltaPhi);
Interpolated[i * Width + j] = Matrix[k][l] * ThetaSinC * PhiSinC + Matrix[k][n] * ThetaSinC * (1 - PhiSinC) + Matrix[m][l] * (1 - ThetaSinC) * PhiSinC + Matrix[m][n] * (1 - ThetaSinC) * (1 - PhiSinC);
}
}
return *Interpolated;
}
我很肯定,在.cpp部分工作得很好。 我使用Visual Studio创建了一个DLL,并通过修改“Multithreaded-DLL(/ MD)”选项之一来使用“Project” - “Project properties” - “C/C++” - “Code generation”。 的DLL已经建立之后,我写了下面的代码在我的VBA程序:
Private Declare Function Shannonize Lib "C:\Users\daquino\Documents\Visual Studio 2013\Projects\FieldTrans\Release\FieldTrans.dll" Alias _
"ShannonInterp" (ByRef Matrix() As Double, ByVal Res As Double, ByVal DeltaTheta As Double, ByVal DeltaPhi As Double) As Double
但它不工作,因为当我使用的功能,它说,它不能在模块中找到。我使用的功能是这样的:
InterpCo = Shannonize(AmplCo, Resolution, 181/(PointsTheta+1), 361/(PointsPhi+1))
提供AmplCo
是双的2D阵列,和其他的输入是整数。
你能帮我理解有什么问题吗?
编辑:如果我尝试从我的VBA程序中插入对.dll的引用,它会显示“引用错误”。
使用dumpbin或Dependency Walker检查DLL的导出。 –
有很多错误。 C++编译器装饰函数的名字以支持重载,你必须用'extern“C”'来关闭它。调用约定是错误的,你必须使用'__stdcall'。 VBA希望将数组编组为“SAFEARRAY”。你不能添加引用,这不是一个COM服务器,Declare就是你所拥有的。迈出一小步去那里,不要试图用一个巨大的口水做这一切,否则你将不可避免地陷入困境。有大量的网页显示如何做到这一点。 –
我一直在阅读各种东西2天,是的,虽然我同意,我不应该在吞下一个时间整个事情,我还是希望* *做到这一点。也许我很愚蠢,但是我没有找到类似于我需要做的事情的例子。即使'extern'也不能按照它应有的方式工作,如果我在头文件*和* che文件中使用它,@VTT指出 – Noldor130884