Created
October 11, 2018 19:01
-
-
Save peteristhegreat/71b441b25c20530c0f0156a83bc2c54b to your computer and use it in GitHub Desktop.
Julia dll cpp dynamic loading
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This (static linking to an archive file) doesn't work because we are using a | |
// different compiler than the one that built julia! | |
//#include <julia.h> | |
//#include <iostream> | |
//using namespace std; | |
//int main()//int argc, char *argv[]) | |
//{ | |
// cout << "Hello World!" << endl; | |
// /* required: setup the Julia context */ | |
// jl_init(); | |
// /* run Julia commands */ | |
// jl_eval_string("print(sqrt(2.0))"); | |
// /* strongly recommended: notify Julia that the | |
// program is about to terminate. this allows | |
// Julia time to cleanup pending write requests | |
// and run all finalizers | |
// */ | |
// jl_atexit_hook(0); | |
// return 0; | |
//} | |
// Heavily based on https://gist.github.com/GunnarFarneback/df2910fa9460cd267b37416f3efea77b | |
// See also https://docs.julialang.org/en/v0.6.0/manual/embedding/ | |
#include <iostream> | |
//#define JULIA_ENABLE_THREADING | |
#include "windows.h" | |
#include "julia.h" | |
// DLL resolution also checks in the PATH environment variable | |
// https://msdn.microsoft.com/en-us/library/7d83bc18.aspx | |
#define JULIA_DIR "C:\\Users\\USERNAME\\AppData\\Local\\Julia-0.6.4" | |
#define DLL_CALL_CONVEN __stdcall | |
#ifdef __cplusplus | |
extern "C" | |
{ | |
#endif | |
// typedef <return type> (DLL_CALL_CONVEN* <func_name>_ptr)(parameter list); | |
typedef void (DLL_CALL_CONVEN* jl_init_ptr)(); | |
typedef jl_value_t* (DLL_CALL_CONVEN* jl_eval_string_ptr)(const char *); | |
typedef void (DLL_CALL_CONVEN* jl_atexit_hook_ptr)(int); | |
#ifdef __cplusplus | |
} | |
#endif | |
using namespace std; | |
std::string GetLastErrorAsString(); | |
int main() | |
{ | |
cout << "Hello World!" << endl; | |
HINSTANCE handle = LoadLibrary(TEXT("libjulia.dll")); // This works if julia.exe is in the path | |
// HINSTANCE handle = LoadLibrary(TEXT(JULIA_DIR "\\bin\\libjulia.dll")); | |
if (handle == NULL){ | |
// Apparently it is not loading when executed inside qtcreator_process_stub | |
// But it will load if executed from Windows Explorer | |
cerr << "ERROR: Failed to open a handle to the dll" << endl; | |
cerr << GetLastErrorAsString() << endl; | |
return 1; | |
} | |
cout << "Library Loaded!" << endl; | |
system("pause"); | |
jl_init_ptr jl_init = (jl_init_ptr)GetProcAddress(handle, "jl_init"); | |
jl_atexit_hook_ptr jl_atexit_hook = (jl_atexit_hook_ptr)GetProcAddress(handle, "jl_atexit_hook"); | |
jl_eval_string_ptr jl_eval_string = (jl_eval_string_ptr)GetProcAddress(handle, "jl_eval_string"); | |
jl_init(); | |
cout << endl << "print(sqrt(2.0))" << endl; | |
jl_eval_string("print(sqrt(2.0))"); | |
jl_atexit_hook(0); | |
cout << endl << "Finished running some julia" << endl; | |
system("pause"); | |
return 0; | |
} | |
// https://stackoverflow.com/questions/1387064/how-to-get-the-error-message-from-the-error-code-returned-by-getlasterror | |
//Returns the last Win32 error, in string format. Returns an empty string if there is no error. | |
std::string GetLastErrorAsString() | |
{ | |
//Get the error message, if any. | |
DWORD errorMessageID = ::GetLastError(); | |
if(errorMessageID == 0) | |
return std::string(); //No error message has been recorded | |
LPSTR messageBuffer = nullptr; | |
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, | |
NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL); | |
std::string message(messageBuffer, size); | |
//Free the buffer. | |
LocalFree(messageBuffer); | |
return message; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment