Calling C++ to sort a vector of strings is more complicated than it seems. The issue is that C++ vectors and Julia vectors are different types, and so are C++ strings and Julia strings. You first need to decide whether you want to use C++ vectors or Julia vectors, C++ strings or Julia strings, or whether you want to convert them as you call C++. Converting needs to copy all data and is thus a bit slower, and if you pass the converted vector back to Julia you get a new vector, you didn’t sort the original vector. You can use C++ vectors and strings from Julia (that’s straightforward). You can also use Julia vector or strings from C++, but that’s more complicate since these new types are not std::vector or std::string, so they won’t have any of the functionality you expect.
Another complication comes form the fact that C++ uses manual memory management, whereas Julia is garbage collected. For any object you handle in C++, you need to decide who “owns” the object, i.e. who is responsible for destroy it when it is no longer needed. A lot of C++'s low-level complexity shines through here. You can use std::shared_ptr<std::vector<...>> or std::shared_ptr<std::string> here to simplify this, if your library allows you to do that.
If you want to use a large, existing C++ library, then I assume you’d be using C++ vectors and C++ strings, and use these from Julia. That’s straightforward; they type CxxVector{T} is a subtype of AbstractVector, and CxxString is a subtype of AbstractString, so Julia will just handle these types “as usual”.
CxxWrap has a nice story for this. It’s a bit more complex that one would like, but there is a good reason for this. I am not aware of a tutorial for what you are trying to do.
If you want to make something really simple work, then sort a C array of C ints instead, i.e. call the equivalent of
int arr[10] = { ... };
std::sort(&arr[0], &arr[10], std::less<int>());
I haven’t tried using clang on Windows yet, but it looks to me like you are not linking to libjulia and libcxxwrap-julia. Even if you link in those, you probably need to compile libcxxwrap-julia from source. I recommend using CMake to set up a project similar to the one here:
That way CMake should set up all link instructions correctly.
Hi @barche, thank you , i have tried to use your cxxwrap-template. Here are the steps I did:
download portable version of VS Code
-install the cmake extension
-downloaded cmake 3.22 portable and added it to PATH
-I cloned your cxxwrap-template repo with git on my local drive
-I have opened the folder in VS Code
-I have opened the file called CMakeLists.txt
-I have run the file using the button at the bottom of VS code (like you describe on github)
-I got an error that the variable JlCxx_DIR was not set, so I did set it to C:\Users\gitboy\.julia\artifacts\...\lib\cmake\JlCxx and re-run
I got the following message:
Cmake Warning at CMakeLists.txt:8 (find_package):
Could not find a configuration file for package "JlCxx" that is compatible with requested version "".
The following configuration files were considered but not accepted:
C:\Users\gitboy\.julia\artifacts\...\lib\cmake\JlCxx\JlCxxConfig.cmake, version: 0.9.0 (64bit)
-- Configuration incomplete, errors occured!
CMake Error at CMakeLists.txt:9 (get_target_property):
get_target_property() called with non-existent target "JlCxx::cxxwrap_julia".
CMake Error at CMakeLists.txt:10 (get_file_name_component):
get_file_name_component called with incorrect number of arguments
I am not sure to understand what is missing, would you have detailed steps on how I can make this work? Thank you
Here, C:/Users/user/source/repos/libcxxwrap-julia/build is the build directory of the libcxxwrap that you compiled with the same compiler as you are using to develop the wrapper.
Thank you @barche for the details. I’ll continue posting here until they move your post to the other thread so people who are looking for help can follow the discussion.
I did what you said and it seemed to have work as I got the following messages:
[cmake] -- Configuration done
[cmake] -- Generating done
[cmake] -- Build files have been written to: D:/cxxwrap-template/build
But I don’t see any .dll or library being created that I can use with @wrapmodule.
This just completed the build file generation phase, you still need to compile by hitting the “Build” button at the bottom or executing the VScode command CMake: Build. The compiled files should then appear in a subdir build
CMakeLists.txt files that I use exactly the same as the one in the git repo of libcxxwrap-julia and cxxwrap-template.
Following instruction of @barche , I can see now the dll in the folder D:\libcxxwrap-julia\build\bin
Then I tried tried to build the dll for cxxwrap-template and got a lot warning messages like that one:
D:\libbcxxwrap-julia\include\jlcxx\module.hpp(183,91): warning C4251: 'jlcxx:::FunctionWrapperBase::m_return_type': struct 'std::pair<jl_datatype_t *, jl_datatype_t *>' needs to have dll-interface to be used by clients of class 'jlcxx::FunctionWrapperBase' [D:\cxxwrap-template\build\foo.vcxproj]
It looks like the dlls I just created for libcxxwrap-julia are not found when I build cxxwrap-template.
Seems there is no error. You are right there is a dll in the folder called D:\cxxwrap-template\build\Debug\foo.dll. There is no bin folder like libcxxwrap-julia. When I try to use the dll in the file testfoo.jl in module ModFoo I have the following error in Julia:
Could not load library "D:\cxxwrap-template\build\Debug\foo.dll"
The specified procedure could not be found.
Stacktrace:
[1] dlopen(s::String, flag::UInt32; throw_error::Bool)
...etc
Is this after loading CxxWrap? Most likely this means that the libcxxwrap-julia DLLs can’t be found. This happens if either CxxWrap is not loaded, or loaded but not using an Overrides.toml to direct to the libcxxwrap-julia you built yourself.
Here is what I have tried after creating the dlls.
Attempt 1:
-Install CxxWrap by typing add CxxWrap without Overrides.toml file created.
-load Cxxwrap with using CxxWrap which loads ok.
-try to run the module in testfoo.jl file
(I get the error message I sent before)
ERROR: InitError: could not load library "C:\Users\gitboy\.julia\artifacts\...\bin\libcxxwrap_julia_stl.dll"
The specified procedure could not be found.
Stacktrace:
[1] dlopen(s::String, flag::UInt32; throw_error::Bool)
...etc
Let’s continue the discussion about the Overrides.toml in the issue linked below, can you please post your full Overrides.toml and the paths to the built DLLs there?
I finally manage to make it work with both MS compiler and LLVM on windows. I can’t explain what the issue was but basically I needed to have a clean installation of Julia ,i.e. the folder C:\Users\gitboy\.julia must be empty except for the Overrides.toml file in the folder artifacts.
Thank you all for your help.