@@ -248,23 +248,66 @@ else
248248fi
249249
250250# --- 6.5 Create C Wrappers ---
251- # Helper functions to extract some info from PROJ in C
251+ # Helper functions to extract some info from PROJ in C and C++
252252log_step " 6.5 Creating C Wrapper Functions"
253253
254- WRAPPER_FILE=" ${TEMP_BUILD_DIR} /proj_wrappers.c "
254+ WRAPPER_FILE=" ${TEMP_BUILD_DIR} /proj_wrappers.cpp "
255255WRAPPER_OBJ_FILE=" ${TEMP_BUILD_DIR} /proj_wrappers.o"
256256
257257DDD=` date +" %Y-%m-%dT%H:%M:%S%z" -u`
258258cat << EOF > ${WRAPPER_FILE}
259259#include "proj.h"
260260#include "math.h"
261261
262+ #include "projapps_lib.h"
263+
264+ #include <emscripten/bind.h>
265+ #include <emscripten/val.h>
266+ #include <vector>
267+ #include <string>
268+
269+ void trampoline(PJ_PROJINFO_LOG_LEVEL level, const char *msg, void *user_data) {
270+ if (!user_data) return;
271+ const emscripten::val* js_callback = reinterpret_cast<const emscripten::val*>(user_data);
272+ (*js_callback)(level, std::string(msg));
273+ }
274+
275+ int projinfo_wrapper(uintptr_t ctx_ptr, emscripten::val jsArgs, emscripten::val jsCallback) {
276+ std::vector<std::string> args = emscripten::vecFromJSArray<std::string>(jsArgs);
277+ std::vector<char*> argv;
278+ for (auto& s : args) {
279+ argv.push_back(&s[0]);
280+ }
281+ PJ_CONTEXT *ctx = reinterpret_cast<PJ_CONTEXT *>(ctx_ptr);
282+ return projinfo(ctx, args.size(), argv.data(), &trampoline, &jsCallback);
283+ }
284+
285+ EMSCRIPTEN_BINDINGS(proj_module) {
286+ emscripten::value_object<PJ_INFO>("PJ_INFO")
287+ .field("major", &PJ_INFO::major)
288+ .field("minor", &PJ_INFO::minor)
289+ .field("patch", &PJ_INFO::patch)
290+ .field("release", std::function<std::string(const PJ_INFO&)>([](const PJ_INFO& i) {
291+ return std::string(i.release); }),
292+ std::function<void(PJ_INFO&, std::string)>([](PJ_INFO& i, std::string v) {}))
293+ .field("version", std::function<std::string(const PJ_INFO&)>([](const PJ_INFO& i) {
294+ return std::string(i.version); }),
295+ std::function<void(PJ_INFO&, std::string)>([](PJ_INFO& i, std::string v) {}));
296+ emscripten::function("proj_info_ems", &proj_info);
297+
298+ emscripten::enum_<PJ_PROJINFO_LOG_LEVEL>("PJ_PROJINFO_LOG_LEVEL")
299+ .value("INFO", PJ_PROJINFO_LOG_LEVEL_INFO)
300+ .value("WARN", PJ_PROJINFO_LOG_LEVEL_WARN)
301+ .value("ERR", PJ_PROJINFO_LOG_LEVEL_ERR);
302+
303+ emscripten::function("projinfo_ems", &projinfo_wrapper, emscripten::allow_raw_pointers());
304+ }
305+
306+ extern "C" {
307+
262308const char* get_compilation_date() {
263309 return "$DDD " ;
264310}
265-
266- int get_proj_info_sizeof() {
267- return sizeof(PJ_INFO);
268311}
269312EOF
270313
@@ -290,6 +333,7 @@ FINAL_LIBS="${INSTALL_DIR}/lib/libproj.a \
290333emcc -v ${FINAL_LIBS} \
291334 -o ${INSTALL_DIR} /projModule.js \
292335 -O3 \
336+ -lembind \
293337 -s STACK_OVERFLOW_CHECK=1 \
294338 -s STACK_SIZE=5MB \
295339 -s NO_DISABLE_EXCEPTION_CATCHING \
@@ -303,7 +347,6 @@ emcc -v ${FINAL_LIBS} \
303347 -s ALLOW_MEMORY_GROWTH=1 \
304348 -s EXPORTED_RUNTIME_METHODS=" [ccall, cwrap, FS, HEAPF64, stringToNewUTF8, UTF8ToString, getValue]" \
305349 -s EXPORTED_FUNCTIONS=" [
306- _get_proj_info_sizeof,
307350 _get_compilation_date,
308351 _proj_info,
309352 _proj_context_errno_string,
0 commit comments