| 2008 | } |
| 2009 | |
| 2010 | void CppExportsGenerator::writeEnd(bool hasPackageInit) |
| 2011 | { |
| 2012 | // generate a function that can be used to validate exported |
| 2013 | // functions and their signatures prior to looking up with |
| 2014 | // GetCppCallable (otherwise inconsistent signatures between |
| 2015 | // client and library would cause a crash) |
| 2016 | if (hasCppInterface()) { |
| 2017 | |
| 2018 | ostr() << std::endl; // #nocov start |
| 2019 | ostr() << "// validate" |
| 2020 | << " (ensure exported C++ functions exist before " |
| 2021 | << "calling them)" << std::endl; |
| 2022 | ostr() << "static int " << exportValidationFunctionRegisteredName() |
| 2023 | << "(const char* sig) { " << std::endl; |
| 2024 | ostr() << " static std::set<std::string> signatures;" |
| 2025 | << std::endl; |
| 2026 | ostr() << " if (signatures.empty()) {" << std::endl; |
| 2027 | |
| 2028 | for (std::size_t i=0;i<cppExports_.size(); i++) { |
| 2029 | const Attribute& attr = cppExports_[i]; |
| 2030 | ostr() << " signatures.insert(\"" |
| 2031 | << attr.function().signature(attr.exportedName()) |
| 2032 | << "\");" << std::endl; |
| 2033 | } |
| 2034 | ostr() << " }" << std::endl; |
| 2035 | ostr() << " return signatures.find(sig) != signatures.end();" |
| 2036 | << std::endl; |
| 2037 | ostr() << "}" << std::endl; |
| 2038 | |
| 2039 | // generate a function that will register all of our C++ |
| 2040 | // exports as C-callable from other packages |
| 2041 | ostr() << std::endl; |
| 2042 | ostr() << "// registerCCallable (register entry points for " |
| 2043 | "exported C++ functions)" << std::endl; |
| 2044 | ostr() << "RcppExport SEXP " << registerCCallableExportedName() |
| 2045 | << "() { " << std::endl; |
| 2046 | for (std::size_t i=0;i<cppExports_.size(); i++) { |
| 2047 | const Attribute& attr = cppExports_[i]; |
| 2048 | ostr() << registerCCallable( |
| 2049 | 4, |
| 2050 | attr.exportedName(), |
| 2051 | attr.function().name() + kTrySuffix); |
| 2052 | ostr() << std::endl; |
| 2053 | } |
| 2054 | ostr() << registerCCallable(4, |
| 2055 | exportValidationFunction(), |
| 2056 | exportValidationFunction()); |
| 2057 | ostr() << std::endl; |
| 2058 | ostr() << " return R_NilValue;" << std::endl; |
| 2059 | ostr() << "}" << std::endl; |
| 2060 | } |
| 2061 | |
| 2062 | // write native routines |
| 2063 | if (!hasPackageInit && (!nativeRoutines_.empty() || !modules_.empty() || !initFunctions_.empty())) { |
| 2064 | |
| 2065 | // build list of routines we will register |
| 2066 | std::vector<std::string> routineNames; |
| 2067 | std::vector<std::size_t> routineArgs; |
no test coverage detected