File: dll_lib.cpp

package info (click to toggle)
cppad 2026.00.00.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 11,584 kB
  • sloc: cpp: 112,960; sh: 6,146; ansic: 179; python: 71; sed: 12; makefile: 10
file content (163 lines) | stat: -rw-r--r-- 3,746 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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
// SPDX-FileCopyrightText: Bradley M. Bell <bradbell@seanet.com>
// SPDX-FileContributor: 2003-25 Bradley M. Bell
// ----------------------------------------------------------------------------

/*
{xrst_begin dll_lib.cpp}
{xrst_spell
   msvc
}

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
}

Restrictions
************
This example is only built and run under the following conditions:

#. The :ref:`cmake-name` command determines that the C compiler is
   gcc, clang, or msvc.

#. The :ref:`cmake-name` command determines it is OK to use
   C++17 features.

#. The :ref:`cmake@cppad_link_flags` do not contain ``-m32`` .


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";
# elif CPPAD_LINK_FLAGS_HAS_M32
   options["compile"] = "gcc -c -fPIC -O2 -m32";
# 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++