gpt4 book ai didi

c++ - 在另一个项目中使用模板函数作为 dll

转载 作者:可可西里 更新时间:2023-11-01 18:29:27 26 4
gpt4 key购买 nike

我有一个像这样的简单函数:

尖点.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)
{
.
.
.
.
.
}

然后我使用这两行创建了一个 dll:

#define EXPORT extern "C" __declspec (dllexport)
EXPORT

我在其他项目中使用这个方法调用了这个函数:

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);

这工作得很好,但现在我把我的功能改成了这个

//#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;
}

但是 Visual Studio 不允许 extern "C"__declspec (dllexport)template functions 有没有办法轻松做到这一点?实际上我不是专家,请你详细解释一下好吗?

最佳答案

没有“模板函数”这样的东西。但是,有一个函数模板;这是一个模板,通过实例化从中创建函数。在这种情况下,区别很重要。

要调用从模板实例化的函数,您必须有权访问该实例化。最常见的情况是在头文件中实现模板并简单地 #include它(有关详细信息,请参阅此 SO question)。我相信您希望您的函数可用于任意客户端提供的类型,如 LinearOperationVector ,因此仅 header 实现是您唯一的选择。


另一方面,如果您知道在构建库时想要实例化模板的所有类型,您实际上可以显式实例化这些类型的模板并导出这些显式实例化.像这样:

头文件

template <typename LinearOperator,typename Vector>
void cuspDsolver(LinearOperator& A,Vector& X,Vector& B,double tol);

源文件

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.

这样的实例化不能是extern "C" , 但是(毕竟它们都具有相同的函数名称)。因此,如果您想动态加载它们,则必须为它们提供唯一命名的 C 链接访问器。

不过,我相信您真正需要的是在头文件中实现函数。


根据您的意见,以下是您如何在内部使用 CUSP 时实际使您的库可动态加载。

您的图书馆的公共(public)界面中不能有函数模板。因此,假设您希望允许将您的库与以下类型的 LinearOperator 一起使用: OperatorCharmOperatorTop , 以及以下类型的 Vector : FancyVector<float>FancyVector<double> .然后,您的公共(public)界面可能如下所示:

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);
}

您甚至不必再显式实例化模板,因为它将为 EXPORT 中的调用隐式实例化。 -ed 函数。

所以实际上,您的公共(public) API 将是那些 4 cuspDsolver_a_b函数,可以正常动态查询。

关于c++ - 在另一个项目中使用模板函数作为 dll,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22008307/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com