diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..600eca2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +################################################################################ +# This .gitignore file was automatically created by Microsoft(R) Visual Studio. +################################################################################ + +/.vs/* +#/docs/wwwroot/lib/* +#/docs/wwwroot/scripts/* +obj/ +bin/ +.git/ +CMakeFiles/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 05896e3..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "dynamicLinker"] - path = dynamicLinker - url = https://github.com/passedbylove/dynamicLinker diff --git a/CoreCLRHost.cpp b/CoreCLRHost.cpp index 3b19d38..1f501ed 100644 --- a/CoreCLRHost.cpp +++ b/CoreCLRHost.cpp @@ -30,12 +30,12 @@ int runFromEntryPoint( std::string tpaList; AddFilesFromDirectoryToTpaList( clrFilesAbsolutePath, tpaList ); - std::cout<<"line 32"<getFunction("coreclr_initialize"); auto coreclr_shutdown = dl->getFunction("coreclr_shutdown"); auto coreclr_create_delegate = dl->getFunction("coreclr_create_delegate"); - std::cout<<"line 37"<open(); coreclr_initialize.init(); @@ -176,7 +176,6 @@ JNIEXPORT jint JNICALL Java_Sample1_intMethod } JNIEXPORT jint JNICALL Java_Sample1_coreClrHost(JNIEnv *env, jobject obj, jstring string) { - std::cout<<"haha"<GetStringUTFChars(string,0); char cap[128]; strcpy(cap,str); @@ -216,7 +215,7 @@ JNIEXPORT jint JNICALL Java_Sample1_coreClrHost(JNIEnv *env, jobject obj, jstrin int exitCode = runFromEntryPoint( cwd, //+std::string("./tar.so"), // absolute path to this exe - std::string("/usr/share/dotnet/shared/Microsoft.NETCore.App/2.2.1/"), // absolute path to coreCLR DLLs + std::string("/usr/share/dotnet/shared/Microsoft.NETCore.App/2.1.30/"), // absolute path to coreCLR DLLs assemblyDir, // absolute path to DLL to run assemblyName, std::string("Managed"), diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9590997 --- /dev/null +++ b/Makefile @@ -0,0 +1,222 @@ +# CMAKE generated file: DO NOT EDIT! +# Generated by "Unix Makefiles" Generator, CMake Version 3.16 + +# Default target executed when no arguments are given to make. +default_target: all + +.PHONY : default_target + +# Allow only one "make -f Makefile2" at a time, but pass parallelism. +.NOTPARALLEL: + + +#============================================================================= +# Special targets provided by cmake. + +# Disable implicit rules so canonical targets will work. +.SUFFIXES: + + +# Remove some rules from gmake that .SUFFIXES does not remove. +SUFFIXES = + +.SUFFIXES: .hpux_make_needs_suffix_list + + +# Suppress display of executed commands. +$(VERBOSE).SILENT: + + +# A target that is always out of date. +cmake_force: + +.PHONY : cmake_force + +#============================================================================= +# Set environment variables for the build. + +# The shell in which to execute make rules. +SHELL = /bin/sh + +# The CMake executable. +CMAKE_COMMAND = /usr/bin/cmake + +# The command to remove a file. +RM = /usr/bin/cmake -E remove -f + +# Escaping for special characters. +EQUALS = = + +# The top-level source directory on which CMake was run. +CMAKE_SOURCE_DIR = /mnt/d/Projects/Nitin/Java2CSharp/Java2CSharp + +# The top-level build directory on which CMake was run. +CMAKE_BINARY_DIR = /mnt/d/Projects/Nitin/Java2CSharp/Java2CSharp + +#============================================================================= +# Targets provided globally by CMake. + +# Special rule for the target rebuild_cache +rebuild_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..." + /usr/bin/cmake -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) +.PHONY : rebuild_cache + +# Special rule for the target rebuild_cache +rebuild_cache/fast: rebuild_cache + +.PHONY : rebuild_cache/fast + +# Special rule for the target edit_cache +edit_cache: + @$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "No interactive CMake dialog available..." + /usr/bin/cmake -E echo No\ interactive\ CMake\ dialog\ available. +.PHONY : edit_cache + +# Special rule for the target edit_cache +edit_cache/fast: edit_cache + +.PHONY : edit_cache/fast + +# The main all target +all: cmake_check_build_system + $(CMAKE_COMMAND) -E cmake_progress_start /mnt/d/Projects/Nitin/Java2CSharp/Java2CSharp/CMakeFiles /mnt/d/Projects/Nitin/Java2CSharp/Java2CSharp/CMakeFiles/progress.marks + $(MAKE) -f CMakeFiles/Makefile2 all + $(CMAKE_COMMAND) -E cmake_progress_start /mnt/d/Projects/Nitin/Java2CSharp/Java2CSharp/CMakeFiles 0 +.PHONY : all + +# The main clean target +clean: + $(MAKE) -f CMakeFiles/Makefile2 clean +.PHONY : clean + +# The main clean target +clean/fast: clean + +.PHONY : clean/fast + +# Prepare targets for installation. +preinstall: all + $(MAKE) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall + +# Prepare targets for installation. +preinstall/fast: + $(MAKE) -f CMakeFiles/Makefile2 preinstall +.PHONY : preinstall/fast + +# clear depends +depend: + $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 1 +.PHONY : depend + +#============================================================================= +# Target rules for targets named sample1 + +# Build rule for target. +sample1: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 sample1 +.PHONY : sample1 + +# fast build rule for target. +sample1/fast: + $(MAKE) -f CMakeFiles/sample1.dir/build.make CMakeFiles/sample1.dir/build +.PHONY : sample1/fast + +#============================================================================= +# Target rules for targets named tar + +# Build rule for target. +tar: cmake_check_build_system + $(MAKE) -f CMakeFiles/Makefile2 tar +.PHONY : tar + +# fast build rule for target. +tar/fast: + $(MAKE) -f CMakeFiles/tar.dir/build.make CMakeFiles/tar.dir/build +.PHONY : tar/fast + +CoreCLRHost.o: CoreCLRHost.cpp.o + +.PHONY : CoreCLRHost.o + +# target to build an object file +CoreCLRHost.cpp.o: + $(MAKE) -f CMakeFiles/tar.dir/build.make CMakeFiles/tar.dir/CoreCLRHost.cpp.o +.PHONY : CoreCLRHost.cpp.o + +CoreCLRHost.i: CoreCLRHost.cpp.i + +.PHONY : CoreCLRHost.i + +# target to preprocess a source file +CoreCLRHost.cpp.i: + $(MAKE) -f CMakeFiles/tar.dir/build.make CMakeFiles/tar.dir/CoreCLRHost.cpp.i +.PHONY : CoreCLRHost.cpp.i + +CoreCLRHost.s: CoreCLRHost.cpp.s + +.PHONY : CoreCLRHost.s + +# target to generate assembly for a file +CoreCLRHost.cpp.s: + $(MAKE) -f CMakeFiles/tar.dir/build.make CMakeFiles/tar.dir/CoreCLRHost.cpp.s +.PHONY : CoreCLRHost.cpp.s + +dynamicLinker/dynamicLinker.o: dynamicLinker/dynamicLinker.cpp.o + +.PHONY : dynamicLinker/dynamicLinker.o + +# target to build an object file +dynamicLinker/dynamicLinker.cpp.o: + $(MAKE) -f CMakeFiles/tar.dir/build.make CMakeFiles/tar.dir/dynamicLinker/dynamicLinker.cpp.o +.PHONY : dynamicLinker/dynamicLinker.cpp.o + +dynamicLinker/dynamicLinker.i: dynamicLinker/dynamicLinker.cpp.i + +.PHONY : dynamicLinker/dynamicLinker.i + +# target to preprocess a source file +dynamicLinker/dynamicLinker.cpp.i: + $(MAKE) -f CMakeFiles/tar.dir/build.make CMakeFiles/tar.dir/dynamicLinker/dynamicLinker.cpp.i +.PHONY : dynamicLinker/dynamicLinker.cpp.i + +dynamicLinker/dynamicLinker.s: dynamicLinker/dynamicLinker.cpp.s + +.PHONY : dynamicLinker/dynamicLinker.s + +# target to generate assembly for a file +dynamicLinker/dynamicLinker.cpp.s: + $(MAKE) -f CMakeFiles/tar.dir/build.make CMakeFiles/tar.dir/dynamicLinker/dynamicLinker.cpp.s +.PHONY : dynamicLinker/dynamicLinker.cpp.s + +# Help Target +help: + @echo "The following are some of the valid targets for this Makefile:" + @echo "... all (the default if no target is provided)" + @echo "... clean" + @echo "... depend" + @echo "... rebuild_cache" + @echo "... edit_cache" + @echo "... sample1" + @echo "... tar" + @echo "... CoreCLRHost.o" + @echo "... CoreCLRHost.i" + @echo "... CoreCLRHost.s" + @echo "... dynamicLinker/dynamicLinker.o" + @echo "... dynamicLinker/dynamicLinker.i" + @echo "... dynamicLinker/dynamicLinker.s" +.PHONY : help + + + +#============================================================================= +# Special targets to cleanup operation of make. + +# Special rule to run CMake to check the build system integrity. +# No rule that depends on this can have commands that come from listfiles +# because they might be regenerated. +cmake_check_build_system: + $(CMAKE_COMMAND) -S$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles/Makefile.cmake 0 +.PHONY : cmake_check_build_system + diff --git a/Managed.cs b/Managed.cs index f56fdd8..fab9fae 100644 --- a/Managed.cs +++ b/Managed.cs @@ -6,16 +6,23 @@ using System; using System.Runtime.InteropServices; -public class Managed { +public class Managed +{ -[UnmanagedFunctionPointer(CallingConvention.ThisCall)] -unsafe delegate void myDelegate( IntPtr thisptr ); + [UnmanagedFunctionPointer(CallingConvention.ThisCall)] + unsafe delegate void myDelegate(IntPtr thisptr); -public static unsafe void runIt( IntPtr thisptr, IntPtr mem_fun ) { - Console.WriteLine("Here's C# code:"); + public static unsafe void runIt(IntPtr thisptr, IntPtr mem_fun) + { + Console.WriteLine(ProcessStatement()); - myDelegate fun = (myDelegate) Marshal.GetDelegateForFunctionPointer( mem_fun, typeof(myDelegate) ); + //myDelegate fun = (myDelegate) Marshal.GetDelegateForFunctionPointer( mem_fun, typeof(myDelegate) ); - fun(thisptr); // first argument of member functions in C++ is "this", but it's hidden from us :-) - } + //fun(thisptr); // first argument of member functions in C++ is "this", but it's hidden from us :-) + } + public static string ProcessStatement() + { + return "In ProcessStatement"; + } } + diff --git a/Managed.csproj b/Managed.csproj index d3aacbb..1f4ad54 100644 --- a/Managed.csproj +++ b/Managed.csproj @@ -1,7 +1,7 @@ library - netcoreapp2.2 + netcoreapp2.1 true diff --git a/Managed.sln b/Managed.sln new file mode 100644 index 0000000..aee6598 --- /dev/null +++ b/Managed.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.10.35027.167 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Managed", "Managed.csproj", "{66E3787C-26B9-4FDC-9329-C6BE4F9288DD}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {66E3787C-26B9-4FDC-9329-C6BE4F9288DD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {66E3787C-26B9-4FDC-9329-C6BE4F9288DD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {66E3787C-26B9-4FDC-9329-C6BE4F9288DD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {66E3787C-26B9-4FDC-9329-C6BE4F9288DD}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {21D43ED0-F3C3-4708-9E53-E577E5B5826F} + EndGlobalSection +EndGlobal diff --git a/README.md b/README.md index 6e12ab0..45a5c3a 100644 --- a/README.md +++ b/README.md @@ -1,25 +1,69 @@ -[![Build Status](https://dev.azure.com/marcozo0520/JavaCallCSharp/_apis/build/status/eisber.JavaCallCSharp?branchName=master)](https://dev.azure.com/marcozo0520/JavaCallCSharp/_build/latest?definitionId=1?branchName=master) - - # JavaCallCSharp Java call C# lib build with .NET CORE 2.0 via C++ as wraper The code is based on [example from coreCLR](https://github.com/dotnet/coreclr/tree/master/src/coreclr/hosts/unixcoreruncommon) Java using JNI to call C++ code. then C++ host a core CLR to run C# code. + +```mermaid +graph LR +Jaava[Java] --> B((C++ .cpp)) +B --> C((Core CLR)) +C --> D[.NET core 2.2] +``` + # pre-require .NET CORE SDK 2.0: I only tested it in Ubuntu 18.04 x64 (Follow https://dotnet.microsoft.com/download/linux-package-manager/ubuntu18-04/sdk-current) -gcc 6: std C++ 14 for the filesystem +If you already have recent version of donet need to remove it + +``` +sudo apt remove dotnet* +``` +Install .NET Core 2.1 SDK (works well if you dont have any dotnet installed, tested Ubuntu 20.04.3 LTS wsl) + +1. Enable Microsoft PPA + +``` +wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb +sudo dpkg -i packages-microsoft-prod.deb +``` + +2. Installing .NET Core 2.1 SDK + +``` +sudo apt update +sudo apt install apt-transport-https +sudo apt install dotnet-sdk-2.1 +``` + +3. Installing build tools (gcc 6: std C++ 14 for the filesystem) + +``` +sudo apt-get update +sudo apt-get install build-essential +sudo apt install cmake +``` + +4. Installing Java + +``` +sudo apt install default-jre +sudo apt install default-jdk +``` # usage: -git submodule init +``` +git init git submodule update +dotnet build Managed.csproj + cmake . cmake --build . +javac Sample1.java java -cp sample1.jar Sample1 +``` - -`You should keep the compiled file in the same fold.` +`You should keep the compiled file in the same folder.` diff --git a/Sample1.class b/Sample1.class new file mode 100644 index 0000000..18db37e Binary files /dev/null and b/Sample1.class differ diff --git a/Sample1.java b/Sample1.java index 3291db2..866d124 100644 --- a/Sample1.java +++ b/Sample1.java @@ -11,18 +11,8 @@ public static void main(String[] args) System.load(System.getProperty("user.dir") + java.io.File.separator + "libtar.so"); Sample1 sample = new Sample1(); - int square = sample.intMethod(5); - boolean bool = sample.booleanMethod(true); - String text = sample.stringMethod("JAVA"); - int sum = sample.intArrayMethod(new int[]{1,1,2,3,5,8,13}); - int success=0; - success= sample.coreClrHost("./bin/Debug/netcoreapp2.2/Managed.dll"); - System.out.println("intMethod: "+ square); - System.out.println("boolMethod: "+ bool); - System.out.println("stringMethod: "+ text); - System.out.println("intArrayMethod: "+ sum); - System.out.println("status:"+success); + int success= sample.coreClrHost("./bin/Debug/netcoreapp2.1/Managed.dll"); } diff --git a/dynamicLinker-backup.zip b/dynamicLinker-backup.zip new file mode 100644 index 0000000..081abf8 Binary files /dev/null and b/dynamicLinker-backup.zip differ diff --git a/libtar.so b/libtar.so new file mode 100644 index 0000000..36ed588 Binary files /dev/null and b/libtar.so differ diff --git a/sample1.jar b/sample1.jar new file mode 100644 index 0000000..aafbb4f Binary files /dev/null and b/sample1.jar differ