File: dll_lib.cpp

package info (click to toggle)
cppad 2025.00.00.2-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 11,552 kB
  • sloc: cpp: 112,594; sh: 5,972; ansic: 179; python: 71; sed: 12; makefile: 10
file content (145 lines) | stat: -rw-r--r-- 3,312 bytes parent folder | download
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++