Importing modules in embedded Janet #1294
-
Hello dear Janet community, I've spend two days now trying to get an example module running in my own C++-hosted environment My stock janet.exe interpreter loads the module without issue, but my embedded Janet (built from amalgamated janet.h and statically linked to libjanet) simply crashes in janet_core_native. It finds _janet_init, tries to execute it, throws an exception or fails after that. The module is comprised of the example code in the Writing a Module example and imports correctly in my janet.exe. My host code source tries to import the module but crashes: // main.cpp
#include <janet.h>
int main(int argc, char **argv)
{
janet_init();
// get core env
JanetTable* ev = janet_core_env(nullptr);
janet_dostring(ev, "(prin \"let's import mymod ...\")", "main", nullptr);
janet_dostring(ev, "(import /mymod)", "main", nullptr);
//< crashes here in janet_core_native
janet_dostring(ev, "(print \"still here.\")", "main", nullptr);
/* Deinitialize vm */
janet_deinit();
return 0;
}
the module source // module.cpp
#include <janet.h>
static Janet myfun(int32_t argc, Janet *argv) {
janet_fixarity(argc, 0);
printf("hello from a module!\n");
return janet_wrap_nil();
}
static const JanetReg cfuns[] = {
{"myfun", myfun, "(mymod/myfun)\n\nPrints a hello message."},
{NULL, NULL, NULL}
};
JANET_MODULE_ENTRY(JanetTable *env) {
janet_cfuns(env, "mymod", cfuns);
} my CMake file to build the module and the host application (can be opened with Visual Studio with File->Open to generate a solution from & build, all these snippets are supposed to be files in the same directory) # CMakeLists.txt
cmake_minimum_required(VERSION 3.19)
# main project
project(modexample)
# change this to your own install
set(JANET_DIST_DIR "C:\\Development\\tools\\janet\\dist")
# Set C++ standard to C++17
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# OpenMP support
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /MD /O2 /openmp /Z7")
set(CMAKE_BUILD_TYPE Release)
set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)
# Add header.h and main.cpp to the project
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
${JANET_DIST_DIR})
# host application
add_executable(modhost ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
target_compile_definitions(modhost PUBLIC -DJANET_BUILD_TYPE=release)
target_link_directories (modhost PUBLIC ${JANET_DIST_DIR})
target_link_libraries (modhost PUBLIC libjanet)
target_link_options (modhost PUBLIC /DEBUG)
# module library
add_library(mymod SHARED ${CMAKE_CURRENT_SOURCE_DIR}/module.cpp)
target_compile_definitions(mymod PUBLIC -DJANET_BUILD_TYPE=release)
target_link_directories (mymod PUBLIC ${JANET_DIST_DIR})
target_link_libraries (mymod PUBLIC janet)
target_link_options (mymod PUBLIC /DEBUG)
install(TARGETS modhost mymod
RUNTIME DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin
LIBRARY DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin
ARCHIVE DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin
DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin
)
I've also tried building the host application directly with the amalgamated .C-file but it doesn't change the crash. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 3 replies
-
Depending on what you are doing, you may just want to compile your library into one large executable. Unfortunately, linking is tricky. I'm curious what flags are being passed to cl.exe when compiling both the main.c and module.c (should be /MD for both). I will try to reproduce locally to see if we can get more guidance on this, but my suspicision is that there is an extra copy of the runtime c runtime library thrown into the mix here, or some different essential option in one of the three components:
|
Beta Was this translation helpful? Give feedback.
Ok, so I have gone over the code a bit and the issue is actually quite simple. The problem is:
which links to janet.lib, which is the import library for janet.exe (yes, the exe file not a DLL). Basically, the lib file is included so native modules can link directly to the standalone interpreter. The app is crashing because you are trying to load janet.exe as a DLL inside modhost.exe. Instead, you need to compile janet.c yourself and link to that from both the modhost.exe and mymod.dll.