我正在尝试构建使用库UMFPACK的简单dll。
这是我的文件" umfsolver.c":
#include <stdio.h>
#include <stdlib.h>
#include "umfpack.h"
#include "amd.h"
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
#ifdef BUILD_DLL
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif
typedef struct problem_struct
{
double Control [UMFPACK_CONTROL];
double Info [UMFPACK_INFO];
int *Ti;
int *Tj;
double *Tx;
int nrow;
int ncol;
int nz;
} problem;
EXPORT problem* __stdcall create(int nrows, int ncols, int nnonzero)
{
problem *prob;
prob = (problem*) malloc(sizeof (problem)) ;
if (!prob) return (NULL);
prob->nrow = nrows;
prob->ncol = ncols;
prob->nz = nnonzero;
printf("Creating...\n");
umfpack_di_defaults (prob->Control) ;
prob->Control [UMFPACK_PRL] = 3 ;
prob->Control [UMFPACK_BLOCK_SIZE] = 32 ;
prob->Ti = (int *) malloc (nnonzero * sizeof (int)) ;
prob->Tj = (int *) malloc (nnonzero * sizeof (int)) ;
prob->Tx = (double *) malloc (nnonzero * sizeof (double)) ;
if (!prob->Ti || !prob->Tj || !prob->Tx ) return (NULL);
return prob;
}
这是我的makefile:
all: libs umfsolver
include ../../SuiteSparse_config/SuiteSparse_config.mk
#-------------------------------------------------------------------------------
# the optional Partition module requires METIS, CAMD, and CCOLAMD
I_WITH_PARTITION =
LIB_WITH_PARTITION =
CONFIG1 = -DNCHOLMOD
CONFIG2 = -DNPARTITION
ifeq (,$(findstring -DNCHOLMOD, $(UMFPACK_CONFIG)))
# CHOLMOD is requested. See if it is available
ifeq (../../CHOLMOD, $(wildcard ../../CHOLMOD))
ifeq (../../COLAMD, $(wildcard ../../COLAMD))
# CHOLMOD and COLAMD are available
CONFIG1 =
LIB_WITH_CHOLMOD = ../../CHOLMOD/Lib/libcholmod.a \
../../COLAMD/Lib/libcolamd.a
# check if METIS is requested and available
ifeq (,$(findstring -DNPARTITION, $(CHOLMOD_CONFIG)))
# METIS is requested. See if it is available
ifeq ($(METIS_PATH), $(wildcard $(METIS_PATH)))
ifeq (../../CAMD, $(wildcard ../../CAMD))
ifeq (../../CCOLAMD, $(wildcard ../../CCOLAMD))
# METIS, CAMD, and CCOLAMD are available
LIB_WITH_PARTITION = $(METIS) \
../../CCOLAMD/Lib/libccolamd.a \
../../CAMD/Lib/libcamd.a
I_WITH_PARTITION = -I$(METIS_PATH)/Lib \
-I../../CCOLAMD/Include -I../../CAMD/Include
CONFIG2 =
endif
endif
endif
endif
endif
endif
endif
#-------------------------------------------------------------------------------
C = $(CC) $(CF) $(UMFPACK_CONFIG) $(CONFIG1) $(CONFIG2) \
-I../Include -I../../AMD/Include -I../../SuiteSparse_config
INC = ../Include/umfpack.h ../../AMD/Include/amd.h ../../SuiteSparse_config/SuiteSparse_config.h
LIBS = $(LAPACK) $(BLAS) $(XERBLA) $(LIB) $(LIB_WITH_CHOLMOD) $(LIB_WITH_PARTITION) $(CUBLAS_LIB) $(CUDART_LIB)
../Lib/libumfpack.a:
( cd ../Lib ; $(MAKE) )
../../AMD/Lib/libamd.a:
( cd ../../AMD ; $(MAKE) library )
../../SuiteSparse_config/libsuitesparseconfig.a:
( cd ../../SuiteSparse_config ; $(MAKE) library )
../../CHOLMOD/Lib/libcholmod.a:
- ( cd ../../CHOLMOD && $(MAKE) library )
../../COLAMD/Lib/libcolamd.a:
- ( cd ../../COLAMD && $(MAKE) library )
../../CCOLAMD/Lib/libccolamd.a:
- ( cd ../../CCOLAMD && $(MAKE) library )
../../CAMD/Lib/libcamd.a:
- ( cd ../../CAMD && $(MAKE) library )
$(METIS):
( cd $(METIS_PATH) && $(MAKE) )
UMFPACK = ../Lib/libumfpack.a ../../AMD/Lib/libamd.a \
../../SuiteSparse_config/libsuitesparseconfig.a \
$(LIB_WITH_CHOLMOD) $(LIB_WITH_PARTITION)
libs: $(UMFPACK)
umfsolver: umfsolver.c $(UMFPACK)
$(C) -c -DBUILD_DLL umfsolver.c
$(C) -shared -o umfsolver.dll umfsolver.o -Wl,--add-stdcall-alias $(UMFPACK) $(LIBS) -lm
我使用了变量:
CF = -O3 -fexceptions -fPIC
CC = cc
LIB = -lm -lrt
UMFPACK_CONFIG = -DNBLAS -LD:/SuiteSparseBuild/UMFPACK/Lib -lsuitesparseconfig -lrt
MAKE = make
CUBLAS_LIB =
CUDART_LIB =
XERBLA =
BLAS =
LAPACK =
METIS_PATH = ../../metis-4.0
METIS = ../../metis-4.0/libmetis.a
它构建没有错误。当我从另一个程序(使用静态dllimport)调用函数create
时,它会起作用,直到需要在create
内调用某个库函数。
当程序调用{{1}}或printf("Creating...\n")
时,程序似乎会进入无限循环。
当我输入make时,我明白了:
umfpack_di_defaults (prob->Control)
我想我应该以某种方式更改makefile以将所有库文件放在一起? 我怎样才能做到这一点?谁能解释一下这个?
谢谢!