Ive built a simple dll in c++ using Visual C++ 2010 and am trying to use it in excel. The project name is "SwapFunDLL", the source files name is "swapmain" and the name of the header file containing the class and its function is "DateNTime". Ive attached them below. The code takes in two values and then uses the class function to multiply them and then returns the product (i realize the class and function arent necessary, im just doing this to learn). The function compiles with not errors however when the function is used in excel i get a value error. Could someone please help me see what im doing wrong thanks.
header:
// DateNTime.h
//Avoid need of .Def file
#ifdef SwapFunDLL_EXPORTS
#define SwapFunDLL_API __declspec(dllexport)
#else
#define SwapFunDLL_API __declspec(dllimport)
#endif
namespace DateNTime
{
class SwapFunDLL_API Date
{
double x,y;
public:
double datediff(double,double);
};
double Date::datediff(double x, double y)
{
return x*y;
}
}
Source File:
#include "DateNTime.h"
namespace DateNTime
{
double returndates(double a, double b)
{
Date Date;
return Date.datediff(a,b);
}
}
Excel Macro:
Declare Function SwapFunDLL _
Lib "C:\Users\MIKE\Desktop\c++ tial programs\SwapFunDLL\Debug\SwapFunDLL.dll" _
(ByRef x As Double, ByRef y As Double) As Double
your import declaration is wrong. Two things: the semantics and declaration of types. If you use pointers than in Excel you say ByRef, but if you use by value passing you say ByVal.
Declare this function as:
Declare Function returndates Lib "C:\Users\MIKE\Desktop\c++ tial programs\SwapFunDLL\Debug\SwapFunDLL.dll" _ (ByVal x As Double, ByVal y As Double) As Double
make your function returndates member of your class that is being exported, static member.
also make your function static and in any case you can declare this export in .def file (just simply: "returdates" it's all). After all of it this has to work unless your C++ code is OK.
also here:
double returndates(double a, double b)
{
Date Date; //<- change it, i.e: Date d; d.datediff(); does it compile?
return Date.datediff(a,b);
}
you can change the code just to test if you do everything correctly to such "test info" form:
double returndates(double a, double b)
{
return 117;
}
and try it in Excel.
Excel needs __stdcall, so make a functions declarations inside your class like this:
static double __stdcall returndates(double a, double b);
then define it in .cpp file as:
SwapFunDLL_API double __stdcall DateNTime::Date::returndtes(double a, double b){
return 117;
}
after all these changes should be OK.
Related
I am trying to use a Visual C++ dll in a VB.NET windows application, both created in VS2010. In the Windows project I can successfully add the dll to my references but only functions without pointer arguments are usable in the program and visible in the object browser. I borrowed a simple example I found and changed one of the function arguments to be a pointer.
header file:
// TestDLL.h
using namespace System;
namespace MathFuncs
{
public ref class MyMathFuncs
{
public:
static double Add(double *a, double B);
static double Subtract(double a, double B);
static double Multiply(double a, double B);
static double Divide(double a, double B);
};
}
cpp file
// TestDLL.cpp
// compile with: /clr /LD
#include "TestDLL.h"
namespace MathFuncs
{
double MyMathFuncs::Add(double *a, double B)
{
return *a + b;
}
double MyMathFuncs::Subtract(double a, double B)
{
return a - b;
}
double MyMathFuncs::Multiply(double a, double B)
{
return a * b;
}
double MyMathFuncs::Divide(double a, double B)
{
if (b == 0)
{
throw gcnew DivideByZeroException("b cannot be zero!");
}
return a / b;
}
}
The dll compiles successfully with no warnings. When I reference the dll in a simple windows form I get the error:
"Error 1 'Add' has a return type that is not supported or parameter types that are not supported."
If I remove the pointer the dll works fine. From other forums I thought the calling convention might be a problem and tried using __stdcall but I got another error saying reference classes can't use __stdcall.
I also tried not referencing the dll and instead declaring the dll functions from a module in the windows application. I got an error saying "entry point not found" which I think is because C++ decorates the function name. I tried dumpbin.exe/EXPORTS "dll PATH" but it would not show the decorated function names. I have also tried creating an module definition file and using extern "c" although I most likely didn't use them properly. All solutions I have found to these problems have been for unmanaged C++ but do not work for managed Visual C++.
I would rather be able to reference the dll because it seems simpler. Any insight would be greatly appreciated.
Change your definition to :
double Add(double % a, double b)
{
return a + b;
}
This compiles as ByRef and works:
I am trying to expose a C++ DLL to Excel using mac. The DLL was written and compiled with Xcode 4 and I am using Excel 2011.
For simple functions, extern "C" does the work and I am able to use the dylib in Excel. Specifically, if the C++ code is something like
extern "C"
{
double sumC( double a, double b)
{
return a + b;
}
}
and the VBA code is:
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
everything works fine. But, I am interested in exposing to Excel more complex code with classes defined in header files - as in the example below - and in that case Excel returns #VALUE!. My C++ code is something like this
header file:
#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 file:
#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();
}
And finally this is the file that contains the function I would like to expose to 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;
}
}
I tried to use the same dylib in a C++ app and works fine, so I believe it is something related to exposing the library through VBA.
The VBA code I used is
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
Any help would be greatly appreciated.
This is of course not necessary but to simplify I will assume from now on that your header file and both source files are in the same directory, and that all future commands are executed in this directory. Then replace in both source files
#include "TestFunction.h"
with
#include "./TestFunction.h"
Then, compile as follows :
g++ -m32 -Wall -g -c ./TestFunction.cpp -o ./TestFunction.o
g++ -m32 -dynamiclib ./file.cpp ./TestFunction.o -o ./libTestDLLtoVBA.dylib
where
g++ is your gcc. I guess it is clang's one, on my computer it is gcc 5.2.0, but both should work fine
file.cpp is the source file containing the declaration of addFunctionC
the -m32 option asks to produce a 32 bits dylib, as excel/VBA on mac are 32 bits
Now do a nm -gU libTestDLLtoVBA.dylib and you will see a line with _addFunctionC showing that the function addFunctionC is exported indeed.
In the VBA, declare as follows :
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
and it should work. This was a great source of inspiration.
Now, if you don't want to used command line and want to use XCode for instance, I would say that the only thing you have to take care of is to ensure that XCode produces a 32 bits dylib, as excel/VBA are 32 bits only on mac OS X. I really think that this 32 bits stuff is your problem.
You likely want to read up on COM automation objects. Sometimes known as "OLE" or "ActiveX". It's essentially a way to expose classes and objects written in C++ to other programming languages.
For scripting environments (VBA and Javascript), the traditional way to do this is by registering a COM object that exposes an IDispatch interface.
Some links to get you started:
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
Don't get hung up on the details of "controls" and embedded UI windows. Foucs on getting a simple COM object class and interface declared in an IDL, generate a typelib, implement a C++ class that implements the interface and IDispatch. ATL (Active Template Library) makes this stuff easy.
I created a new WIN32 C++ project. I didn't touch any of the code in the main file yet, and started to write my code in a different file objectsFW.cpp the definitions for the file are located in the file objectsFW.h.
objFW.h looks like:
#pragma once
double g;
typedef struct {
double x;
double y;
}Vector;
typedef struct {
//...
}BoundingBox;
typedef struct {
//...
}Ball;
Vector operator + (Vector a, Vector b) {
//...
}
Vector operator - (Vector a, Vector b) {
//...
}
There are some more operators defined, and the declarations of the functions.
I included the header file in the source file (objectsFW.cpp), and also, added it to the Resources.h file, so that my code will be useable in the main program.
I get linker errors:
Error 1 error LNK2005: "struct Vector __cdecl operator*(struct Vector,double)" (??D#YA?AUVector##U0#N#Z) already defined in ObjectsFW.obj C:\testC\ObjectsCollision\ObjectsCollision\ObjectsCollision.obj ObjectsCollision
...
Error 4 error LNK2005: "struct Vector __cdecl operator+(struct Vector,struct Vector)" (??H#YA?AUVector##U0#0#Z) already defined in ObjectsFW.obj C:\testC\ObjectsCollision\ObjectsCollision\ObjectsCollision.obj ObjectsCollision
and so on.
I know that this happens because the #include "objectFW.h" line appears two times (once in each .cpp file). The question is what is the right way to declare the header file to avoid linker errors?
UPDATE:
After turning the operator functions to inline most of the errors fixed, there is still a program with the line:
double g;
the error is:
Error 1 error LNK2005: "double g" (?g##3NA) already defined in ObjectsCollision.obj C:\testC\ObjectsCollision\ObjectsCollision\ObjectsFW.obj ObjectsCollision
(working on Visual Studio 2012)
About global variables:
1. Refrain from using them. Think encapsulation and data hiding.
2. If you must use them, define the global in 1 source file and place the "extern" in a header file.
Example:
header_file.hpp:
extern unsigned int deadly_global;
source_file.cpp:
unsigned int deadly_global;
Better method for hiding global variables
A better method for controlling (hiding) global variables is to place all the code that uses the variable in the same source file and declare the variable as static:
static unsigned int variable_shared_by_many_functions = 0;
void f1(void)
{
variable_shared_by_many_functions = 42U;
}
void f2(void)
{
std::cout << "Value of shared variable: "
<< variable_shared_by_many_functions
<< "\n";
}
Controlling Global Variables Using Getters and Setters
If you must share the variable among functions in more than one source file, a safer technique is to declare the variable as static in one source file and declare functions (interfaces) to access it.
static int dangerous_variable = 0;
int accessor(void)
{
// Return a copy of the varible.
return dangerous_variable;
}
void setter(int new_value)
{
if ((new_value / 5) != 1)
{
dangerous_variable = new_value;
}
}
This technique allows you to place filters or other controls on setting the variable.
Put in your header:
extern double g;
And in a .cpp:
double g;
That way every file that includes the header will know that there is a variable g, but it will only be declared at one place.
I am trying to define a function using Rcpp for speedup. The situation is as follows:
I have a package FOO with a lot of C++ code (my own package and currently not using Rcpp) which have defined a set of functions e.g. foo_a and foo_b.
In another package BAR (using Rcpp) I am defining a function (using Rcpp Attributes) where I want to call functions foo_a and foo_b.
How do I solve this? Looking a bit in other posts I get that I have in some way to include header files in FOO and use attribute // [[Rcpp::depends(FOO)]] in BAR, but I seem to miss some points. Any hints on how to do it?
Best Lars
EDIT: Thanks for the comments I liked Kevin Usheys approach and tried to implement it. However, after some coding I realized that I actually don't need functions from FOO but a class and its public functions. I guess that I cannot do the tricks you suggested for a class. I ended up putting the source files of the class from FOO in the BAR src dir (not the best approach since I now have 2 versions of the same code). However for the moment this hack work for me.
I would recommend one of these options:
If foo_a and foo_b are simple enough, just have them as inline functions in headers of FOO and put these headers in FOO/inst/include/FOO.h. Rcpp::depends(FOO) will then include this file when you invoke compileAttributes (or perhaps load_all) on BAR.
Otherwise, consider registering the functions using R's registration model. this is a bit more work, but that's bearable. Writing R extensions has the details. I would suggest putting all the registration logic in FOO so that the client package BAR only has to use it. For example, I'd have foo_a like this in FOO's headers, e.g. in FOO/inst/include/FOO.h:
#ifdef COMPILING_FOO
inline int foo_a(int x, double y, const std::string& z){
typedef int (*Fun)(int, double, const std::string&) ;
static Fun fun = (Fun)R_GetCCallable( "FOO", "foo_a" ) ;
return fun(x,y,z) ;
}
#else
// just declare it
int foo_a(int x, double y, const std::string& z) ;
#endif
and the actual definition of foo_a in some .cpp file in FOO/src:
#define COMPILING_FOO
#include <FOO.h>
int foo_a(int x, double y, const std::string& z){
// do stuff
}
Then, you need to register foo_a using R_RegisterCCallable in the function R_init_FOO:
extern "C" void R_init_FOO( DllInfo* info ){
R_RegisterCCallable( "FOO", "foo_a", (DL_FUNC)foo_a );
}
Another option, in case you don't mind introducing Rcpp into package FOO - follow along with Section 3.5 of Rcpp-attributes and do the following:
Place // [[Rcpp::interfaces(cpp)]] at the top of the .cpp source files containing functions you'd like to be made available to other packages,
Place // [[Rcpp::export]] in front of those functions you would like exported,
Call compileAttributes() in the package directory of FOO to generate files in inst/include that can then be used by package BAR, using // [[Rcpp::depends(FOO)]],
Install package FOO.
If you have this set up correctly, you should be able to call a function with a template like this (supposing foo_a is an exported function from FOO):
// [[Rcpp::depends(FOO)]]
#include <Rcpp.h>
#include <FOO.h>
using namespace Rcpp;
// [[Rcpp::export]]
SEXP some_function() {
return FOO::foo_a();
}
The RcppXts package does just that for a bunch of functions from the well-known xts package.
Edit: Here is some code from xts.
First, xts::src/init.c does the registration via a dozen or so declarations like
R_RegisterCCallable("xts","do_is_ordered",(DL_FUNC) &do_is_ordered);
Second, xts::inst/include/xtsApi.h provides a header for client packages with eg
SEXP attribute_hidden xtsIsOrdered(SEXP x, SEXP increasing, SEXP strictly) {
static SEXP(*fun)(SEXP,SEXP,SEXP) = NULL;
fun = (SEXP(*)(SEXP,SEXP,SEXP)) R_GetCCallable("xts","do_is_ordered");
return fun(x, increasing, strictly);
}
Third, in a client package such as RcppXts we define this (using Rcpp Modules) as
function("xtsIsOrdered",
&xtsIsOrdered,
List::create(Named("x"),
Named("increasing") = true,
Named("strictly") = true),
"Tests whether object is (strictly) (increasing) ordered");
which exposes it to R. We could equally well call the C function xtsIsOrdered from C++ code.
I removed the incorrect earlier comment that functions have to conform to 'SEXP in, SEXP out'.
I was writing a program of function overloading in Visual C++ 2010 .
Following is my code
// overload.cpp : Defines the entry point for the console application.
#include<Windows.h>
#include<iostream>
#include<conio.h>
using namespace std;
//abs is overloaded in 3 types
int abs(int i);
double abs(double d);
long abs(long f);
void main()
{
cout<<abs(-10)<<"\n";
cout<<abs(-11.0)<<"\n";
cout<<abs(-9L)<<"\n";
getch();
}
int abs(int i)
{
cout<<"using integer abs()\n";
return i>0? -i:i;
}
double abs(double d)
{
cout<<"using double abs()\n";
return d>0? -d:d;
}
long abs (long l)
{
cout<<"using long abs()\n";
return l>0?-l:l;
}
I am having problems in double abs and long abs function that
1>c:\users\abc\documents\visual studio 2010\projects\overload\overload\overload.cpp(22): error C2084: function 'double abs(double)' already has a body
1>c:\users\abc\documents\visual studio 2010\projects\overload\overload\overload.cpp(26): error C2084: function 'long abs(long)' already has a body
Why this problem is coming?
I have changed the compilation from c to c++
but recently I ran an other program for overloading,it worked.I don't know how? here is the code.
#include<iostream>
#include<cstdio>
#include<conio.h>
#include<cstring>
using namespace std;
void stradd(char*s1,char*s2);
void stradd(char*s1,int i);
void main()
{
char str[80];
strcpy(str,"hello");
stradd(str,"there");
cout<<str<<"\n";
getch();
}
//concatenate a string with a "stringized "integer
void stradd(char*s1,int i)
{
char temp[80];
sprintf(temp,"%d",i);
strcat(s1,temp);
}
//concatenate 2 strings
void stradd(char*s1,char *s2)
{
strcat(s1,s2);
}
and output is hellothere
Your problem comes from a header in which abs is declared for some types such as double. You're not allowed to have to functions with exactly the same header (that is, same return type, same name, same list of parameters, same qualifiers such as const).
There are two ways of avoiding this:
Use the standard library: std::abs is good, you don't need to implement it yourself
Naming the method absoluteValue or myAbs or whatever you like, but not abs
A third way, namely removing using namespace std does not work according to your comment. This is because you include Windows.h. This itself includes a bunch of headers, probably including math.h. This gives a method called abs in the global namespace. Better don't include Windows.h and include cmath if you need to. Then, abs is only declared in namespace std, hence you can call it with std::abs and is different from abs.
When overload resolution cannot select one function as the unique best match, the call is ambiguous. An ambiguous call produces a compilation error.
In std there is already an abs() with the following signature:
int abs (int n);
So while you try to overload it with double and long it results in ambiguity for the compiler.
If you're a beginner learning about coding i suggest you to use function names not defined in libraries (at least the ones you have included).
stefan have already given the solution to it:
Remove using namespace std; and explicitly write std::cout
OR
Re name your function to absoluteValue or something else
OR
Use explicit namespaces in function declaration and calls. (Not tested, though it should work)
Put your function inside a class or namespace.
Maybe this would provide you with a little insight (From SO).
EDIT:
The second question's overloaded functions stradd() is not defined in any other library. That is why no Compilation Errors. The following function signature in your code will result an error: char * strcat ( char * destination, const char * source )
Your primary problem is that you use global namespace. Just declare your function in your own namespace and all name collisions will be gone.
Let me explain why you're getting those compile-time errors.
Somewhere in the headers you included there are double abs(double) and long abs(long) functions. Then you're creating functions with the same signatures by your own. So compiler just don't know what to use when you'll call one of them - there are 2 pairs of equal functions. So it refuses to compile that, and you're getting those errors.
So you have 2 choices - hope that every time you'll want to create a function you will choose an unique name, or just create a namespace and your function names should be unique only to another functions in your namespace.
And it's not about overloading - void func(int i) overloads void func(float f), but void func(int i) overrides void func(int i). You can override superclass member functions in subclasses, but you cannot override standalone functions like abs().
just change abs function name with another.
abs() is a keyword therefore it is showing errors.