Trying to pass in a user supplied string which has a path to the jvm.dll but it doesn’t load the library unless I hard code with the following:
#define RUNTIME_DLL _T("C:\\Program Files\\Java\\jre7\\bin\\Server\\jvm.dll")
It compiles but fails if I try this:
HINSTANCE handle = LoadLibrary((const char*)Marshal::StringToHGlobalAnsi(string).ToPointer());
The “string” var has the exact copy and pasted path that _T() has but still fails. Not an expert in C/C++ so I’m not sure what _T() gets it to work.
Update:
Tried this:
// System::String always stored as Unicode, get a Unicode pointer with no conversion necessary
pin_ptr<const WCHAR> lib_name = PtrToStringChars(string);
// Always use the Unicode version of LoadLibrary
HINSTANCE handle = LoadLibraryW(lib_name);
And still it won’t load the jvm.dll file. It will only load it if I do this:
#define RUNTIME_DLL _T("C:\\Program Files\\Java\\jre7\\bin\\Server\\jvm.dll")
// System::String always stored as Unicode, get a Unicode pointer with no conversion necessary
pin_ptr<const WCHAR> lib_name = PtrToStringChars(RUNTIME_DLL);
// Always use the Unicode version of LoadLibrary
HINSTANCE handle = LoadLibraryW(lib_name);
Tried this as well:
// System::String always stored as Unicode
marshal_context^ ctx = gcnew marshal_context();
pin_ptr<const WCHAR> lib_name = PtrToStringChars(jvmDllPath);
//const wchar_t * lib_name = ctx->marshal_as<const wchar_t*, System::String^>(jvmDllPath);
printf("JVM Path: %s", lib_name);
// Always use the Unicode version of LoadLibrary
handle = LoadLibraryW(lib_name);
if( handle == 0) {
printf("Failed to load jvm dll \n");
//printf(ErrorExit((LPTSTR)(const char*)"Initialize"));
// this is the part that will work
System::String^ string = gcnew System::String("C:\\Program Files\\Java\\jre7\\bin\\Server\\jvm.dll");
pin_ptr<const WCHAR> lib_name = PtrToStringChars(string);
handle = LoadLibraryW(lib_name);
}
delete ctx; // do this for now to not create memory leaks
The C++/CLI method signature is:
void Initialize(String^ jvmDllPath)
The body is basically the code above
The C# code that calls into this with a string parameter is this:
obj.Initialize("c:\\program files\\java\\jdk7\\jre\\bin\\server\\jvm.dll");
Providing answer here from Ben’s suggestion so people/newbs and temporary c/c++/cli coders can find a quick answer to avoid what I went through:
const char * CliToNativeString(String^ cliString){
const char * converted;
converted = (gcnew marshal_context())->marshal_as<const char *>( cliString );
return converted;
}
String^ NativeToCliString(const char * nString){
String^ converted = gcnew String("");
if(nString != NULL)
converted = (gcnew marshal_context())->marshal_as<String^>(nString);
return converted;
}
There are better ways for getting a C-style string from a
System::String^. Have a look at themarshal_asandmarshal_contexttemplates supplied with VC++.Your immediate problem here is that you are compiling for Unicode, so
LoadLibraryrequires a unicode string, butStringToHGlobalAnsidoes not return a unicode string. No amount of pointer casting will change the encoding of the string pointed to.You also have a memory leak.
Try this instead:
If this works and the above doesn’t, then something is wrong with the string sent from C#: