I have a simple function like this:
cusp.dll
#define EXPORT extern "C" __declspec (dllexport)
EXPORT
void cuspDsolver(int *r, int *c, double *v, double *x, double *b, int size, int nnz,double tol)
{
.
.
.
.
.
}
and I created a dll using these two lines:
#define EXPORT extern "C" __declspec (dllexport)
EXPORT
and I called this function in other Project using this method:
HINSTANCE hDLL = LoadLibrary("C:\\Users\\Administrator\\Documents\\Visual Studio 2012\\Projects\\Ardalan_12\\cusp.dll");
if(hDLL == NULL)
{
cout<< "Failed to load DLL" <<endl;
}
typedef void(*fnPtr)(int *, int *, double *, double *, double *, int , int ,double);
fnPtr pfn;
pfn=(fnPtr)GetProcAddress(hDLL,"cuspDsolver");
if(pfn)
{
pfn(rowOffset,colIndex,values,answer,rightHandSide,theSize,nnz,0.9);
}
FreeLibrary(hDLL);
this works very fine, but now I changed my function to this
//#define EXPORT extern "C" __declspec (dllexport)
//EXPORT
template <typename LinearOperator,typename Vector>
void cuspDsolver(LinearOperator& A,Vector& X,Vector& B,double tol)
{
cusp::default_monitor<double> monitor(B, 10000, tol);
cusp::precond::scaled_bridson_ainv<double,cusp::device_memory> PRE(A);
DWORD dw1 = GetTickCount();
cusp::krylov::cg(A,X,B,monitor,PRE);
DWORD dw2 = GetTickCount();
double dw3 = dw2 - dw1;
cout <<endl << "time spent is : " << dw3 << endl;
cout << endl << "developed by cusp!!!" << endl;
}
but Visual Studio won't allow extern "C" __declspec (dllexport) with template functions is there any way to do this easily?actually I'm not expert,so would you please explain this to me in detail?
There is no such thing as a "template function." There is a function template, however; that is a template from which functions are created by instantiation. In this case, the distinction is important.
To call a function instantiated from a template, you must have access to that instantiation. The most common case is to implement the template in a header file and simply #include it (see this SO question for more details). I believe that you want your function to be usable with arbitrary client-supplied types as LinearOperation and Vector, so a header-only implementation is your only option.
If, on the other hand, you know all the types you would want to instantiate the template with when building your library, you can actually explicitly instantiate the template for those types and export these explicit instantiations. Like this:
Header file
template <typename LinearOperator,typename Vector>
void cuspDsolver(LinearOperator& A,Vector& X,Vector& B,double tol);
Source file
template <typename LinearOperator,typename Vector>
void cuspDsolver(LinearOperator& A,Vector& X,Vector& B,double tol)
{
// body here
}
template __declspec(dllexport) void cuspDsolver(MyConcreteOperator1& A, MyConcreteVector1& X, MyConcreteVector1& B, double tol);
template __declspec(dllexport) void cuspDsolver(MyConcreteOperator2& A, MyConcreteVector2& X, MyConcreteVector2& B, double tol);
// etc.
Such instantiations cannot be extern "C", however (they all have the same function name, after all). So if you want to load them dynamically, you'll have to provide uniquely-named C-linkage accessors to them.
Still, I believe what you're really looking for is implementing the funciton in a header file.
Based on your comments, here is how you could actually make your library dynamically loadable while using CUSP internally.
You cannot have a function template in your library's public interface. So let's say you want to allow using your library with the following types of LinearOperator: OperatorCharm and OperatorTop, and with the following types of Vector: FancyVector<float> and FancyVector<double>. Then, your public interface could look like this:
template <typename LinearOperator,typename Vector>
void cuspDsolver(LinearOperator& A,Vector& X,Vector& B,double tol)
{
// body
}
EXPORT void cuspDsolver_Charm_float(params_which, correspond_to, OperatorCharm_and, FancyVector_of_float)
{
cuspDsolver(params);
}
EXPORT void cuspDsolver_Charm_double(params_which, correspond_to, OperatorCharm_and, FancyVector_of_double)
{
cuspDsolver(params);
}
EXPORT void cuspDsolver_Top_float(params_which, correspond_to, OperatorTop_and, FancyVector_of_float)
{
cuspDsolver(params);
}
EXPORT void cuspDsolver_Charm_double(params_which, correspond_to, OperatorTop_and, FancyVector_of_double)
{
cuspDsolver(params);
}
You don't even have to instantiate the template explicitly any more, since it will be instantiated implicitly for the calls in the EXPORT-ed functions.
So in effect, your public API will be those 4 cuspDsolver_a_b functions, which can be queried dynamically as normal.
Template functions are not compiled and thus not part of a DLL as there's an infinite number of function derived from a template.
Only specific instances of the template are compiled and linked into a binary. You can expose those specialized template functions in a DLL. You'll need a header file for those names as string them in a hardcoded string is problematic.
If you want to use a template function w/o specializing it, export it through a header file.
Related
I am currently trying to create a wrapper interface that can translate C++ to C, and while studying on the possibilities to do that, I came across the template functions (and classes). Knowing that these functions can take any data type and return any data type as well, I find it hard to create a corresponding caller function name that C could read. A simple example is the adder.
template <class typesToAdd>
typesToAdd addStuff(typesToAdd a, typesToAdd b) {
return a + b;
}
My interface includes the extern "C" command to avoid the C++ name mangling in C.
Template is not a function that works for any data type. It is a template for a function that is created at compilation time. Each type you use creates a new function with a new symbol in the binary.
To export to C, you will have to specialize the type you want to use from C, like:
template <class typesToAdd>
typesToAdd addStuff(typesToAdd a, typesToAdd b) {
return a + b;
}
extern "C" {
int addStuffInt(int a, int b) {
return addStuff(a, b);
}
}
You may use function templates to simplify both implementing and maintaining the actual code that does the work but to provide a C interface, you'll still need to explicitly instantiate the functions for the types you aim to support.
If you'd like a C++ user to have the same restricted access to the functions as a C user will have, you can move the template implementation into the .cpp file and do the explicit instantiation there. A C++ user trying to use the function with types for which you have not explicitly instantiated the template will get a linking error.
It could look something like this:
// a.hpp
#pragma once
template <class T>
T addStuff(const T& a, const T& b); // no implementation here.
// a.cpp
#include "a.hpp"
#include "a.h"
template <class T>
T addStuff(const T& a, const T& b) {
T rv = a;
rv += b;
return rv;
}
// C interface - note: it's inside the .cpp file
extern "C" {
int add_ints(int a, int b) {
return addStuff(a, b);
}
double add_doubles(double a, double b) {
return addStuff(a, b);
}
}
/* a.h */
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
int add_ints(int, int);
double add_doubles(double, double);
#ifdef __cplusplus
}
#endif
A C user can now include the .h file and call the two functions for which you've provided an implementation.
Example:
// main.c
#include "a.h"
#include <stdio.h>
int main() {
printf("%d\n", add_ints(10, 20));
printf("%f\n", add_doubles(3., .14159));
}
Compilation:
g++ -c a.cpp
gcc -o main main.c a.o
i'm trying to implement a clone of the json serialization library nlohmann::json as a learning experience, and i'm having trouble with the interface for user defined (json<->User type) conversion.
Basically i want the user to be able to overload two function: to_json(json&, const Type&) and from_json(const json&, Type&). Then the library will use overload resolution to call theses function in the templated operator= and one argument constructor.
It works fine when i'm just defining theses function directly but when i try to make a template definition for multiple types (in this example the class S) the linker can't find the definition.
I've tried to explicitly instantiate the function for individual instances of the templated class although i would prefer avoiding having to do that in the final product.
I'm guessing it has to do with the fact that templated function don't have the same signature than free function, but i don't see what i can do to make it work. What am i missing ? I also couldn't find result on google so is it a documented pattern or an anti pattern ?
Thanks you. Below i tried to minimize my problem in one short example.
Class.hpp
#pragma once
#include <cstdio>
template<size_t i>
class S {
size_t n = i;
};
template<size_t i>
void g(const S<i>& s) {
printf("S<%u>\n", i);
}
Class.cpp
#include "Class.hpp"
template void g<10>(const S<10>&); // <-- Even with explicitly instanciation
void g(const bool& b) {
printf("%s\n", b ? "true" : "false");
}
main.cpp
#include "Class.hpp"
template<typename T>
void f(T t) {
extern void g(const T&);
g(t);
}
int main(int, char**) {
S<10> s;
//f(s); <-- linker error: void g(class S<10> const &) not found.
f(false);
}
The name lookup for g in g(t) call stops as soon as it finds extern void g(const T&); declaration; it never sees the declaration of the function template. So the compiler generates a call to a regular non-template function named g taking const S<10>&. But no such function is defined in your program - hence linker error.
I am using OpenCV for some image manipulation and it has several functions that must be given a data type to perform correctly. My idea is to template these functions so I do not have to write a separate function for each possible data type it could be.
However, the code I would like the code I am writing to be compatible with some existing C code I have that stores images in memory so I can pass it around easier without writing the image to disc constantly.
The problem I am running into is how to make my .h files and libraries to let the C program call the C++ template functions. I have not had a chance to try it yet, but so far what I have would look something what follows:
foo.h
int foo(int a, int, b);
float foo(float a, float b);
foo.c:
int foo(int a, int b) {
return footemp(a, b);
}
float foo(float a, float b) {
return footemp(a, b);
}
foo.hpp:
template<class t>
t footemp(t a, t b) {
return a + b;
}
Which does not work since it requires my .c file to know about a templated file.
So I am open to suggestions. Thank you in advance for the help
This is possible, with some care. Use a C++ source file foo.cpp:
#include "foo.h"
#include "footemp.hpp"
int foo_int(int a, int b) {
return footemp(a, b);
}
float foo_float(float a, float b) {
return footemp(a, b);
}
In foo.h, use extern "C" to make C-compatible declarations, with an #ifdef to allow use as either C or C++:
#ifdef __cplusplus
extern "C" {
#endif
int foo_int(int a, int, b);
float foo_float(float a, float b);
#ifdef __cplusplus
}
#endif
Compile this as a C++ library—static or dynamic, it doesn’t matter. In your C sources you can now #include "foo.h" and use these functions as you would expect, so long as you link against the library.
I imagine one thing you could do is write the function in C++, declaring the specializations you want, and at the same time defining extern "C" functions that forward the calls to the template functions.
Keep in mind if you're using C for the other stuff, you're going to need to name the functions different; C doesn't do function overloading.
As mday299 mentioned, there is no templates in C.
However, if your C code is contained in a saparate compilation unit (.exe/.dll), you can provide C interface for your template functions almost like you did it:
foo.h
/* C interface */
int fooInt(int a, int, b);
float fooFloat(float a, float b);
foo.hpp
template <class T> foo(T a,T b)
{
return a+b;
}
foo.cpp:
#include "foo.h"
#include "foo.hpp"
int fooInt(int a, int b) {
return foo<int>(a, b);
}
float fooFloat(float a, float b) {
return foo<float>(a, b);
}
Then, project would be compiled separate using c++, and c part would see only foo.h and lib/dll file
No templates in C. That's a C++ feature. Sorry.
There is a good chance that you'll be able to compile your C file with a C++ compiler. So you can build your whole project, both C and C++ sources with a C++ compiler.
You are already compiling it with a C++ compiler, otherwise you wouldn't be able to compile your overloaded foo functions.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Name mangling of c++ classes and its member functions?
I created a Visual C++ dll. It is working and i can call my Thrust methods from cuda through this dll in c#.
The only problem is, that i am not able to unmangle the function names. I would like to have the normal names so i would not need to use an Entrypoint with the convention.
Here is my code.
This is my header
//ThrustCH.h
#pragma once
enter code here__declspec(dllexport) class ThrustFuncs
{
__declspec(dllexport) static int maxValueThrust(int *data, int N);
__declspec(dllexport) static double maxValueThrust(double *data, int N);
__declspec(dllexport) static int* sort(int* data, int N);
__declspec(dllexport) static double* sort(double* data, int N);
__declspec(dllexport) static int simple(int N);
};
This is my cpp
// thrustDLL.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "thrustH.h"
#include "thrustCH.h"
extern "C" {
__declspec(dllexport) int ThrustFuncs::maxValueThrust(int *data, int N){
return thrustH::maxValue(data,N);
}
__declspec(dllexport) double ThrustFuncs::maxValueThrust(double *data, int N){
return thrustH::maxValue(data,N);
}
__declspec(dllexport) int* ThrustFuncs::sort(int* data, int N){
return thrustH::sort(data,N);
}
__declspec(dllexport) double* ThrustFuncs::sort(double* data, int N){
return thrustH::sort(data,N);
}
__declspec(dllexport) int ThrustFuncs::simple(int N){
return N;
}
}
I tried to use extern "C" and __declspec(dllexport) almost everywhere put i guess I'm doing something wrong. Could you help me please?
It seems you are trying to export C++ functions but want them to have a C name.
There is no direct way to do that, mainly because it doesn't make sense.
C doesn't have classes (or namespaces for that matter) and those usually are involved in the C++ name mangling. That is, don't write the functions you intend to export with a C name decoration in a class declaration.
You can, however, still write C functions (in an extern "C" block) in which you call your C++ functions, methods, or classes.
Something like:
class foo
{
static int bar(const std::string& str) { return static_cast<int>(str.size()); }
}
extern "C"
{
int bar(const char* str)
{
// Call C++ version of the function.
try
{
return foo::bar(str);
}
catch (std::exception&)
{
// Handle it somehow
}
}
}
You may want to use __cdecl for the functions that you want to export which will not mangle the names.
Refer: /Gd, /Gr, /Gz (Calling Convention)
Here's some simplified code to demonstrate the problem I have.
I have a template function for which I only wish to compile certain fixed instantiations.
The function declarations are:
// *** template.h ***
int square (int x);
double square (double x);
The definitions are:
// *** template.cpp ***
#include "template.h"
// (template definition unusually in a code rather than header file)
template <typename T>
T square (T x)
{
return x*x;
}
// explicit instantiations
template int square (int x);
template float square (float x);
And, an example use is:
// *** main.cpp ***
#include <iostream>
using namespace std;
#include "template.h"
int main (void)
{
cout << square(2) << endl;
cout << square(2.5) << endl;
}
An attempt to compile this results in a link errors, roughly:
main.obj : unresolved external symbol "int square(int)" referenced in function main
I understand what the problem is: the function signatures of my explicit template instantiations do not match those in the header file.
What is the syntax for the (forward) declaration of the explicit template instantiations please? I do not wish to forward declare the template definition, or to move the template definition into a header file.
For what it's worth, I do have a workaround, which is to use wrapper functions, adding the following to the above files:
// *** template.cpp ***
// ...
// wrap them [optionally also inline the templates]
int square (int x) { return square<> (x); }
double square (double x) { return square<> (x); }
That compiles and works as expected. However, this seems like a hack to me. There should be something more elegant than this available in C++ and template syntax.
Any help or hints would be much appreciated.
You need to declare the function template in your header:
template <typename T>
T square(T x);
As you have it now, you declare two nontemplate functions in the header, which are never defined.
There is no other way if you want to hide the template from the header file. You have to have wrapper functions because int square (int x); does not have the same name mangling as template int square (int x); and C++ does not offer you a way to change that.
You can check out how name mingling differs in Visual Studio as an example.