Reputation: 994
I needed to write a DLL in C++ containing a couple of functions that I'd be later using in VBA.
The .h file I've written looks like this (though, I admit I have been copying from some examples on the internet since I am very new to C++, and I'm not sure I need all this stuff):
// 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
While the .cpp file contains the actual definition of those functions:
// 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;
}
I'm quite positive that the .cpp part works just fine. I created a DLL by using Visual Studio and using "Project"-"Project properties"-"C/C++"-"Code generation" by modifying one of the options to "Multithreaded-DLL (/MD)". After the DLL had been created, I wrote the following code in my VBA program:
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
But it doesn't work, since when I use the function, it says that it cannot be found in the module. I'm using the function like this:
InterpCo = Shannonize(AmplCo, Resolution, 181 / (PointsTheta+1), 361 / (PointsPhi+1))
Provided AmplCo
is a 2D-array of Double, and the others inputs are Integer.
Could you please help me understand what's wrong?
EDIT: if I try to insert a reference to the .dll from my VBA program, it says "bad reference".
Upvotes: 0
Views: 94
Reputation: 37488
It looks like names of the C++ functions that you are exporting from dll have been mangled. Unlike C, C++ functions can be overloaded (same name but different arguments), can dwell in namespaces, etc. so names of exported functions will also include some extra suffixes. You can either surround exported functions with extern "C" { /*your code*/ }
block to prevent name mangling or write a module exports file (.def) with proper naming.
Upvotes: 1