我有一个像这样的简单函数:
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)
{
.
.
.
.
.
}
Run Code Online (Sandbox Code Playgroud)
我用这两行创建了一个dll:
#define EXPORT extern "C" __declspec (dllexport)
EXPORT
Run Code Online (Sandbox Code Playgroud)
我使用这种方法在其他Project中调用了这个函数:
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);
Run Code Online (Sandbox Code Playgroud)
这工作得很好,但现在我改变了我的功能
//#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;
}
Run Code Online (Sandbox Code Playgroud)
但是Visual Studio不允许使用模板函数的extern"C"__declspec(dllexport)有什么方法可以轻松地做到这一点吗?实际上我不是专家,所以请你详细解释一下这个问题?
没有"模板功能"这样的东西.但是,有一个功能模板 ; 这是一个模板,通过实例化从中创建函数.在这种情况下,区别很重要.
要调用从模板实例化的函数,您必须有权访问该实例.最常见的情况是在头文件中简单地实现模板#include(有关更多详细信息,请参阅此SO问题).我相信,你希望你的函数与任意客户端提供的类型,使用LinearOperation和Vector,因此只有头的实现是你唯一的选择.
另一方面,如果您知道在构建库时要实例化模板的所有类型,则可以实际显式地为这些类型实例化模板并导出这些显式实例化.像这样:
头文件
template <typename LinearOperator,typename Vector>
void cuspDsolver(LinearOperator& A,Vector& X,Vector& B,double tol);
Run Code Online (Sandbox Code Playgroud)
源文件
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.
Run Code Online (Sandbox Code Playgroud)
extern "C"然而,这样的实例化不能(毕竟它们都具有相同的功能名称).因此,如果要动态加载它们,则必须为它们提供唯一命名的C链接访问器.
不过,我相信你真正想要的是在头文件中实现功能.
根据您的评论,以下是在内部使用CUSP时实际可以动态加载库的方法.
您的库的公共界面中不能有功能模板.因此,假设您希望允许使用具有以下类型的库LinearOperator:OperatorCharm和OperatorTop,以及以下类型Vector:FancyVector<float>和FancyVector<double>.然后,您的公共接口可能如下所示:
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);
}
Run Code Online (Sandbox Code Playgroud)
您甚至不必再显式实例化模板,因为它将隐式实例化EXPORT-ed函数中的调用.
因此,实际上,您的公共API将是那4个cuspDsolver_a_b函数,可以像往常一样动态查询.
| 归档时间: |
|
| 查看次数: |
2226 次 |
| 最近记录: |