Skip to content

Commit 7e21d03

Browse files
authored
Add files via upload
1 parent b4204a4 commit 7e21d03

8 files changed

Lines changed: 492 additions & 0 deletions

File tree

‎CoreCLRHost.cpp‎

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
/*
2+
* Copyright (c) Hubert Jarosz. All rights reserved.
3+
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
4+
*/
5+
#include <iostream>
6+
#include <string.h>
7+
#include "CoreCLRHost.hpp"
8+
#include "utils.hpp"
9+
#include "Sample1.h"
10+
11+
int runFromEntryPoint(
12+
std::string currentExeAbsolutePath,
13+
std::string clrFilesAbsolutePath,
14+
std::string managedAssemblyAbsoluteDir,
15+
std::string assemblyName,
16+
std::string entryPointType,
17+
std::string entryPointName)
18+
{
19+
std::cout<<"currentExeAbsolutePath="<<currentExeAbsolutePath<<std::endl<<"clrFilesAbsolutePath="<<clrFilesAbsolutePath<<std::endl<<"managedAssemblyAbsoluteDir="<<managedAssemblyAbsoluteDir<<std::endl<<"assemblyName="<<assemblyName<<std::endl;
20+
std::cout<<"entryPointType="<<entryPointType<<std::endl<<"entryPointName="<<entryPointName<<std::endl;
21+
std::string coreClrDllPath = clrFilesAbsolutePath + "/" + coreClrDll;
22+
23+
24+
if ( coreClrDllPath.size() >= PATH_MAX ) {
25+
std::cerr << "Path to libcoreclr.so too long!" << std::endl;
26+
return -1;
27+
}
28+
29+
std::string nativeDllSearchDirs = managedAssemblyAbsoluteDir + ":" + clrFilesAbsolutePath;
30+
31+
std::string tpaList;
32+
AddFilesFromDirectoryToTpaList( clrFilesAbsolutePath, tpaList );
33+
std::cout<<"line 32"<<std::endl;
34+
auto dl = dynamicLinker::dynamicLinker::make_new( coreClrDllPath );
35+
auto coreclr_initialize = dl->getFunction<coreclrInitializeFunction>("coreclr_initialize");
36+
auto coreclr_shutdown = dl->getFunction<coreclrShutdownFunction>("coreclr_shutdown");
37+
auto coreclr_create_delegate = dl->getFunction<coreclrCreateDelegateFunction>("coreclr_create_delegate");
38+
std::cout<<"line 37"<<std::endl;
39+
try {
40+
dl->open();
41+
coreclr_initialize.init();
42+
coreclr_shutdown.init();
43+
coreclr_create_delegate.init();
44+
} catch ( dynamicLinker::openException e ) {
45+
std::cerr << "Cannot find " << coreClrDll << "Path that was searched: "
46+
<< coreClrDllPath << std::endl;
47+
std::cerr << e.what() << std::endl;
48+
return -1;
49+
} catch ( dynamicLinker::symbolException e ) {
50+
std::cerr << "Probably your libcoreclr is broken or too old." << std::endl;
51+
std::cerr << e.what() << std::endl;
52+
return -1;
53+
} catch ( dynamicLinker::dynamicLinkerException e ) {
54+
std::cerr << e.what() << std::endl;
55+
return -1;
56+
}
57+
58+
const char *propertyKeys[] = {
59+
"TRUSTED_PLATFORM_ASSEMBLIES",
60+
"APP_PATHS",
61+
"APP_NI_PATHS",
62+
"NATIVE_DLL_SEARCH_DIRECTORIES",
63+
"AppDomainCompatSwitch"
64+
};
65+
66+
const char *propertyValues[] = {
67+
tpaList.c_str(),
68+
managedAssemblyAbsoluteDir.c_str(),
69+
managedAssemblyAbsoluteDir.c_str(),
70+
nativeDllSearchDirs.c_str(),
71+
"UseLatestBehaviorWhenTFMNotSpecified"
72+
};
73+
74+
void* hostHandle = NULL;
75+
unsigned int domainId = 0;
76+
int status = -1;
77+
78+
// initialize coreclr
79+
try {
80+
status = coreclr_initialize (
81+
currentExeAbsolutePath.c_str(),
82+
"simpleCoreCLRHost",
83+
sizeof(propertyKeys) / sizeof(propertyKeys[0]),
84+
propertyKeys,
85+
propertyValues,
86+
&hostHandle,
87+
&domainId
88+
);
89+
} catch ( dynamicLinker::dynamicLinkerException e ) {
90+
std::cerr << e.what() << std::endl;
91+
return -1;
92+
}
93+
94+
if ( status < 0 ) {
95+
std::cerr << "ERROR! coreclr_initialize status: 0x" << std::hex << status << std::endl;
96+
return -1;
97+
}
98+
99+
// Fancy modern C++ code. You can also just use void *.
100+
auto no_del = []( auto x ) { (void)(x); };
101+
auto csharp_runIt = std::unique_ptr<csharp_runIt_t, decltype(no_del)>(nullptr, no_del);
102+
103+
try {
104+
// create delegate to our entry point
105+
status = coreclr_create_delegate (
106+
hostHandle,
107+
domainId,
108+
assemblyName.c_str(),
109+
entryPointType.c_str(),
110+
entryPointName.c_str(),
111+
reinterpret_cast<void**>(&csharp_runIt)
112+
);
113+
} catch ( dynamicLinker::dynamicLinkerException e ) {
114+
std::cerr << e.what() << std::endl;
115+
return -1;
116+
}
117+
118+
if ( status < 0 ) {
119+
std::cerr << "ERROR! coreclr_create_delegate status: 0x" << std::hex << status << std::endl;
120+
return -1;
121+
}
122+
123+
myClass tmp = myClass();
124+
tmp.question();
125+
126+
/*
127+
* If arguments are in in different order then second arg is 0 in C#.
128+
* probably something with padding/offset/ptr byte size
129+
*/
130+
(*csharp_runIt)( tmp, std::mem_fun_ref(&myClass::print) );
131+
132+
try {
133+
status = coreclr_shutdown ( hostHandle, domainId );
134+
} catch ( dynamicLinker::dynamicLinkerException e ) {
135+
std::cerr << e.what() << std::endl;
136+
return -1;
137+
}
138+
139+
if ( status < 0 ) {
140+
std::cerr << "ERROR! coreclr_shutdown status: 0x" << std::hex << status << std::endl;
141+
return -1;
142+
}
143+
144+
return 0;
145+
}
146+
147+
148+
JNIEXPORT jint JNICALL Java_Sample1_intMethod
149+
(JNIEnv *env, jobject obj, jint num){
150+
return num * num;
151+
}
152+
JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod
153+
(JNIEnv *env, jobject obj, jboolean boolean){
154+
return !boolean;
155+
}
156+
JNIEXPORT jstring JNICALL Java_Sample1_stringMethod
157+
(JNIEnv *env, jobject obj, jstring string){
158+
const char *str = env->GetStringUTFChars(string,0);
159+
char cap[128];
160+
strcpy(cap,str);
161+
env->ReleaseStringUTFChars(string , str);
162+
return env->NewStringUTF(cap);
163+
}
164+
165+
JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod
166+
(JNIEnv *env, jobject obj, jintArray array){
167+
int i, sum=0;
168+
jsize len = env->GetArrayLength(array);
169+
jint *body = env ->GetIntArrayElements(array,0);
170+
for (i=0;i<len;i++)
171+
{
172+
sum+=body[i];
173+
}
174+
env->ReleaseIntArrayElements(array, body,0);
175+
return sum;
176+
}
177+
JNIEXPORT jint JNICALL Java_Sample1_coreClrHost(JNIEnv *env, jobject obj, jstring string)
178+
{
179+
std::cout<<"haha"<<std::endl;
180+
const char *str = env->GetStringUTFChars(string,0);
181+
char cap[128];
182+
strcpy(cap,str);
183+
std::string dllpath(cap); //"./Managed.dll";
184+
env->ReleaseStringUTFChars(string , str);
185+
// std::string dllpath = env->NewStringUTF(cap);
186+
std::string cwd = SCCH_fs::current_path();
187+
cwd += "/";
188+
std::cout<<"dll path :"<<dllpath<<std::endl;
189+
190+
std::string assemblyName(dllpath);
191+
std::string assemblyDir(assemblyName);
192+
193+
194+
if( !assemblyName.size() ) {
195+
std::cerr << "ERROR: Bad ASSEMBLY_PATH !" << std::endl;
196+
return 0;
197+
}
198+
199+
size_t find = assemblyName.rfind('/');
200+
if( find == std::string::npos )
201+
find = 0;
202+
203+
assemblyName = assemblyName.substr( find+1, assemblyName.size() );
204+
205+
if( assemblyName.size() < 5 ||
206+
assemblyName.substr( assemblyName.size()-4,
207+
assemblyName.size()) != ".dll" ) {
208+
std::cerr << "ERROR: Assembly is not .dll !" << std::endl;
209+
return 0;
210+
}
211+
212+
assemblyName = assemblyName.substr( 0, assemblyName.size()-4 );
213+
214+
assemblyDir.erase(find); // get dir of assembly
215+
assemblyDir = cwd + assemblyDir;
216+
217+
int exitCode = runFromEntryPoint(
218+
cwd+std::string("./tar.so"), // absolute path to this exe
219+
std::string("/usr/share/dotnet/shared/Microsoft.NETCore.App/2.0.0-preview1-002111-00/"), // absolute path to coreCLR DLLs
220+
assemblyDir, // absolute path to DLL to run
221+
assemblyName,
222+
std::string("Managed"),
223+
std::string("runIt"));
224+
225+
if ( exitCode < 0 )
226+
std::cout << "Exit Code: " << exitCode << std::endl;
227+
228+
229+
return 1;
230+
}
231+
232+
int main( int argc, char* argv[] ) { return 0;}

‎CoreCLRHost.hpp‎

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) Hubert Jarosz. All rights reserved.
3+
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
4+
*/
5+
6+
//#pragma once
7+
8+
//#if not defined (__unix__) && not defined(__unix) && not defined (unix) && ( (not defined (__APPLE__) || not defined (__MACH__)) )
9+
// #error THIS SOFTWARE IS ONLY FOR UNIX-LIKE SYSTEMS!
10+
//#endif
11+
12+
#include <functional>
13+
#include <iostream>
14+
#include "dynamicLinker/dynamicLinker.hpp"
15+
16+
// getcwd on Linux
17+
#include <unistd.h>
18+
19+
// PATH_MAX on Linux
20+
#include <limits.h>
21+
22+
#if not defined PATH_MAX
23+
#warning Is this GNU/Hurd? Then this code could occupy a lot of memory.
24+
#include <stdio.h>
25+
#define PATH_MAX FILENAME_MAX
26+
#endif
27+
28+
//#if defined(__APPLE__)
29+
// std::string coreClrDll = "libcoreclr.dylib";
30+
//#else
31+
std::string coreClrDll = "libcoreclr.so";
32+
//#endif
33+
34+
class myClass {
35+
private:
36+
int value;
37+
public:
38+
void question() { value = 42; }
39+
void print() { std::cout << "Value: " << value << std::endl; }
40+
};
41+
42+
typedef void (csharp_runIt_t)( myClass&, std::mem_fun_ref_t<void, myClass> );

‎Makefile‎

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
2+
OS_NAME = $(shell uname -s)
3+
ifeq ($(OS_NAME), Darwin)
4+
CXX = g++-6
5+
ifeq (, $(shell which $(CPP)))
6+
$(error "$(CPP) not found! You need to install gcc 6 to build this!")
7+
endif
8+
else
9+
CXX = g++
10+
endif
11+
12+
CXXFLAGS = -Wall -std=c++14 -m64 -fPIC
13+
LDLIBS = -ldl -lstdc++fs
14+
JAVALIB= -I/usr/lib/jvm/java-9-openjdk-amd64/include -I/usr/lib/jvm/java-9-openjdk-amd64/include/linux/
15+
.PHONY: all clean
16+
17+
all: tar.so Makefile
18+
19+
tar.so: CoreCLRHost.cpp CoreCLRHost.hpp utils.hpp Sample1.h Makefile
20+
git -C dynamicLinker pull || git clone https://github.com/Marqin/dynamicLinker
21+
make -C dynamicLinker CXX=$(CXX)
22+
$(CXX) $(JAVALIB) $(CXXFLAGS) CoreCLRHost.cpp -shared -o tar.so -LdynamicLinker/ -ldynamicLinker $(LDLIBS)
23+
24+
25+
clean:
26+
rm -rf tar.so
27+
sh -c "stat dynamicLinker/ &> /dev/null && make -C dynamicLinker clean" || true
28+
29+
distclean: clean
30+
rm -rf dynamicLinker/

‎Managed.cs‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright (c) Hubert Jarosz. All rights reserved.
3+
* Licensed under the MIT license. See LICENSE file in the project root for full license information.
4+
*/
5+
6+
using System;
7+
using System.Runtime.InteropServices;
8+
9+
public class Managed {
10+
11+
[UnmanagedFunctionPointer(CallingConvention.ThisCall)]
12+
unsafe delegate void myDelegate( IntPtr thisptr );
13+
14+
public static unsafe void runIt( IntPtr thisptr, IntPtr mem_fun ) {
15+
Console.WriteLine("Here's C# code:");
16+
17+
myDelegate fun = (myDelegate) Marshal.GetDelegateForFunctionPointer( mem_fun, typeof(myDelegate) );
18+
19+
fun(thisptr); // first argument of member functions in C++ is "this", but it's hidden from us :-)
20+
}
21+
}

‎Sample1.cpp‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#include "Sample1.h"
2+
#include <string.h>
3+
#include <iostream>
4+
JNIEXPORT jint JNICALL Java_Sample1_intMethod
5+
(JNIEnv *env, jobject obj, jint num){
6+
return num * num;
7+
}
8+
9+
JNIEXPORT jboolean JNICALL Java_Sample1_booleanMethod
10+
(JNIEnv *env, jobject obj, jboolean boolean){
11+
return !boolean;
12+
}
13+
14+
JNIEXPORT jstring JNICALL Java_Sample1_stringMethod
15+
(JNIEnv *env, jobject obj, jstring string){
16+
const char *str = env->GetStringUTFChars(string,0);
17+
char cap[128];
18+
strcpy(cap,str);
19+
env->ReleaseStringUTFChars(string , str);
20+
return env->NewStringUTF(cap);
21+
}
22+
23+
JNIEXPORT jint JNICALL Java_Sample1_intArrayMethod
24+
(JNIEnv *env, jobject obj, jintArray array){
25+
int i, sum=0;
26+
jsize len = env->GetArrayLength(array);
27+
jint *body = env ->GetIntArrayElements(array,0);
28+
for (i=0;i<len;i++)
29+
{
30+
sum+=body[i];
31+
}
32+
33+
env->ReleaseIntArrayElements(array, body,0);
34+
return sum;
35+
}

0 commit comments

Comments
 (0)