I managed to get something going:
Needs["CCompilerDriver`"]
src = "
#include \"WolframLibrary.h\"
#include <boost/date_time/gregorian/gregorian.hpp>
EXTERN_C DLLEXPORT int dow(WolframLibraryData libData,
mint Argc, MArgument *Args, MArgument Res) {
mint year = MArgument_getInteger(Args[0]);
mint month = MArgument_getInteger(Args[1]);
mint day = MArgument_getInteger(Args[2]);
boost::gregorian::date date(year, month, day);
MArgument_setInteger(Res, date.day_of_week().as_number());
return LIBRARY_NO_ERROR;
}
";
dowlib = CreateLibrary[src, "dow",
"Language" -> "C++",
"IncludeDirectories" -> {Environment["BOOSTDIR"]},
"LibraryDirectories" -> {Environment["BOOSTLIBDIR"]},
"CompileOptions" -> {"/EHsc"}]
A few notes:
EXTERN_C
is required to stop C++ mangling the name
- The compile option
/EHsc
is required to enable C++ exceptions.
- Your environment variables / boost directories will vary.
Load it up:
dow = LibraryFunctionLoad[dowlib, "dow", {Integer, Integer, Integer}, Integer]
Test it out:
dow[2012, 6, 22]
5
RandomDateList[] := {RandomInteger[{1800, 2100}], RandomInteger[{1, 12}],
RandomInteger[{1, 28}], RandomInteger[{0, 23}], RandomInteger[{0, 59}],
RandomInteger[{0, 59}]};
RandomDates[n_] := Table[RandomDateList[], {n}]
d = RandomDates[100000];
dow[Sequence @@ #[[;; 3]]] & /@ d // AbsoluteTiming // Short
{0.6562500,{6,6,1,2,5,3,4,0,0,3,0,<<99978>>,6,6,3,1,4,5,6,5,4,4,4}}
Huzzah!
Don't forget to unload it if you want to recompile:
LibraryFunctionUnload[dow]
FYI:
CCompilers[]
(* -> {{Name->Visual Studio,
Compiler->CCompilerDriver`VisualStudioCompiler`VisualStudioCompiler,
CompilerInstallation->c:\Program Files\Microsoft Visual Studio 9.0,
CompilerName->Automatic}} *)
"Language"->"c++"
. (I don't know if the language spec should be"c++"
,c++
,"C++"
, orC++
, as the docs are silent on that point. So, you'll have to try them until they don't give you errors.) $\endgroup$