1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>
// SPDX-FileContributor: 2003-22 Bradley M. Bell
// ----------------------------------------------------------------------------
/*
{xrst_begin dll_lib.cpp}
dll_lib: Example and Test
#########################
options
*******
The following subsection of this example sets
:ref:`create_dll_lib@options` that are different
from the default options:
{xrst_literal
// BEGIN_OPTIONS
// END_OPTIONS
}
Source
******
{xrst_literal
// BEGIN C++
// END C++
}
{xrst_end dll_lib.cpp}
*/
// BEGIN C++
# include <filesystem>
# include <fstream>
# include <vector>
# include <map>
# include <cppad/utility/create_dll_lib.hpp>
# include <cppad/utility/link_dll_lib.hpp>
# if _WIN32
# define DIR_SEP '\\'
# define DLL_EXT ".dll"
# else
# define DIR_SEP '/'
# define DLL_EXT ".so"
# endif
// CALL_CONVENTION, CALL_IMPORT
# ifdef _MSC_VER
# define CALL_CONVENTION __cdecl
# define CALL_IMPORT __declspec(dllimport)
# else
# define CALL_CONVENTION
# define CALL_IMPORT
# endif
namespace {
extern "C"
typedef CALL_IMPORT int (CALL_CONVENTION *function_ptr)(int x, int y);
}
bool dll_lib(void)
{ bool ok = true;
//
// add_source
std::string add_source =
"int add(int x, int y)\n"
"{ return x + y; }\n"
;
//
// dll_entry_source
std::string dll_entry_source =
"extern int add(int x, int y);"
# ifdef _MSC_VER
"__declspec(dllexport) int _cdecl dll_entry(int x, int y)\n"
# else
"int dll_entry(int x, int y)\n"
# endif
"{ return add(x, y);}"
;
//
// temp_dir
std::string temp_dir = std::filesystem::temp_directory_path().string();
if( temp_dir.back() != DIR_SEP )
temp_dir += DIR_SEP;
//
// ofs
std::ofstream ofs;
//
// add_file
std::string add_file = temp_dir + "add.c";
ofs.open(add_file.c_str(), std::ofstream::out);
ofs << add_source;
ofs.close();
//
// dll_entry_file
std::string dll_entry_file = temp_dir + "dll_entry.c";
ofs.open(dll_entry_file.c_str(), std::ofstream::out);
ofs << dll_entry_source;
ofs.close();
//
// BEGIN_OPTIONS
// Example using options that are different from the default options
std::map< std::string, std::string > options;
# ifdef _MSC_VER
options["compile"] = "cl /EHs /EHc /c /TC /O2";
# else
options["compile"] = "gcc -c -fPIC -O2";
# endif
// END_OPTIONS
//
// dll_file
std::vector< std::string > csrc_files(2);
csrc_files[0] = add_file;
csrc_files[1] = dll_entry_file;
std::string dll_file = temp_dir + "dll_entry" + DLL_EXT;
CppAD::create_dll_lib(dll_file, csrc_files, options);
//
// dll_linker
std::string err_msg;
CppAD::link_dll_lib dll_linker(dll_file, err_msg);
if( err_msg != "" )
{ std::cerr << "dll_lib error: " << err_msg << "\n";
return false;
}
//
// dll_entry
void* vptr = dll_linker("dll_entry", err_msg);
if( err_msg != "" )
{ std::cerr << "dll_lib error: " << err_msg << "\n";
return false;
}
function_ptr dll_entry = reinterpret_cast<function_ptr>(vptr);
//
// z = dll_entry(x, y)
int x = 1, y = 2;
int z = dll_entry(x, y);
//
// ok
ok &= z == (x + y);
//
return ok;
}
// END C++
|