patterncppMinor
SAFEARRAY export from a C++ DLL to VBA
Viewed 0 times
safearraydllexportvbafrom
Problem
My code is not very elegant, but I'm a total newbie in c++ and I consider it already a major achievement that I managed to write something that actually works.
As background, I'm defining in VBA the function below, contained in "FieldTrans.dll":
and using it by having:
I thought it'd work like a charm, but it doesn't (yet). Meanwhile I'd like more improvement on the execution time. Therefore the only thing I can optimize is the c++ code contained in the dll, which is:
```
// FieldTrans.h
#ifdef FIELDTRANS_EXPORTS
#define FIELDTRANS_API __declspec(dllexport)
#else
#define FIELDTRANS_API __declspec(dllimport)
#endif
#include
// Returns the normalized cardinal sinus coefficient
FIELDTRANS_API double _stdcall SinC(double x);
extern "C"
{
// Returns the interpolated field matrix: 180° x 360° with Res step
FIELDTRANS_API VARIANT _stdcall ShannonInterp(VARIANT Matrix, int MatrixHeight, int MatrixWidth, double Res, double DeltaTheta, double DeltaPhi);
};
// FieldTrans.cpp
#include "stdafx.h"
#include "FieldTrans.h"
#include
#include
#include
double _stdcall SinC(double x)
{
static const double PI = 3.14159265358979323846;
double y;
y = 1;
if (x != 0) y = sin(PI x) / (PI x);
return y;
}
VARIANT _stdcall ShannonInterp(VARIANT Matrix, int MatrixHeight, int MatrixWidth, double Res, double DeltaTheta, double DeltaPhi)
{
int k, l, m, n;
double iRes, jRes;
double ThetaSinC, PhiSinC;
int Height = static_cast (180 / Res + 1);
int Width = static_cast (360 / Res + 1);
k = 0; m = 1;
long indi[2];
As background, I'm defining in VBA the function below, contained in "FieldTrans.dll":
Private Declare Function ShannonInterp Lib "[Here the name of my path]\FieldTrans.dll" _
(ByVal Matrix As Variant, ByVal MatrixHeight As Integer, ByVal MatrixWidth As Integer, ByVal Res As Double, ByVal DeltaTheta As Double, ByVal DeltaPhi As Double) As Variantand using it by having:
Dim InterpCo As Variant
InterpCo = ShannonInterp(AmplCo, PointsTheta, PointsPhi, Resolution, 181 / (PointsTheta+1), 361 / (PointsPhi+1))I thought it'd work like a charm, but it doesn't (yet). Meanwhile I'd like more improvement on the execution time. Therefore the only thing I can optimize is the c++ code contained in the dll, which is:
```
// FieldTrans.h
#ifdef FIELDTRANS_EXPORTS
#define FIELDTRANS_API __declspec(dllexport)
#else
#define FIELDTRANS_API __declspec(dllimport)
#endif
#include
// Returns the normalized cardinal sinus coefficient
FIELDTRANS_API double _stdcall SinC(double x);
extern "C"
{
// Returns the interpolated field matrix: 180° x 360° with Res step
FIELDTRANS_API VARIANT _stdcall ShannonInterp(VARIANT Matrix, int MatrixHeight, int MatrixWidth, double Res, double DeltaTheta, double DeltaPhi);
};
// FieldTrans.cpp
#include "stdafx.h"
#include "FieldTrans.h"
#include
#include
#include
double _stdcall SinC(double x)
{
static const double PI = 3.14159265358979323846;
double y;
y = 1;
if (x != 0) y = sin(PI x) / (PI x);
return y;
}
VARIANT _stdcall ShannonInterp(VARIANT Matrix, int MatrixHeight, int MatrixWidth, double Res, double DeltaTheta, double DeltaPhi)
{
int k, l, m, n;
double iRes, jRes;
double ThetaSinC, PhiSinC;
int Height = static_cast (180 / Res + 1);
int Width = static_cast (360 / Res + 1);
k = 0; m = 1;
long indi[2];
Solution
Formatting
Notice that I "wrapped" a lot of code in single lines to save some time to the processor going through them... I know it's not conventional, but I'm really looking to speed this up the most...
Let's start with that. At least in every implementation of which I'm aware, C++ is compiled. The compiler reads through your source code, converts it to machine code, links in any libraries you've used, and generates an executable file as its output. The speed of execution is completely unrelated to the source code formatting. Moving more onto one line will not make a single iota of difference in the speed at which the code executes.
Speed
Since you say speed is a major concern, the next obvious point would probably be the use of a "safe array". Even if your result needs to go in a safe array, you probably want to use something like
Notice that I "wrapped" a lot of code in single lines to save some time to the processor going through them... I know it's not conventional, but I'm really looking to speed this up the most...
Let's start with that. At least in every implementation of which I'm aware, C++ is compiled. The compiler reads through your source code, converts it to machine code, links in any libraries you've used, and generates an executable file as its output. The speed of execution is completely unrelated to the source code formatting. Moving more onto one line will not make a single iota of difference in the speed at which the code executes.
Speed
Since you say speed is a major concern, the next obvious point would probably be the use of a "safe array". Even if your result needs to go in a safe array, you probably want to use something like
std::vector during the computation, then copy the result into a safe array when you're done. At least at first glance, it looks like your algorithm is \$O(N^2)\$, so for a large matrix, this could still be a pretty big win--at least the last time I looked, SafeArrayGetElement and SafeArrayPutElement were quite a bit slower than vector's operator[].Context
StackExchange Code Review Q#161743, answer score: 2
Revisions (0)
No revisions yet.