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:
试图传递一个用户提供的字符串,该字符串有通向jvm的路径。dll,但它没有加载库,除非我用下面的硬编码:
#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.
“string”var有正确的复制和粘贴路径,但仍然失败。不是C/ c++方面的专家,所以我不确定是什么_T()让它起作用。
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:
它仍然不会加载jvm。dll文件。只有当我这样做时,它才会装载它:
#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:
c++ /CLI方法签名为:
void Initialize(String^ jvmDllPath)
The body is basically the code above
主体基本上就是上面的代码
The C# code that calls into this with a string parameter is this:
使用字符串参数调用c#的代码是:
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:
从Ben的建议中提供答案,所以人们/newbs和临时c/c++/cli程序员可以找到一个快速的答案来避免我所经历的:
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;
}
1 个解决方案
#1
3
There are better ways for getting a C-style string from a System::String^
. Have a look at the marshal_as
and marshal_context
templates supplied with VC++.
有更好的方式获得c风格的字符串从一个系统:^:字符串。看看vc++提供的marshal_as和marshal_context模板。
Your immediate problem here is that you are compiling for Unicode, so LoadLibrary
requires a unicode string, but StringToHGlobalAnsi
does not return a unicode string. No amount of pointer casting will change the encoding of the string pointed to.
这里的直接问题是要编译Unicode,因此LoadLibrary需要一个Unicode字符串,但是StringToHGlobalAnsi不返回Unicode字符串。任何数量的指针转换都不会改变指向的字符串的编码。
You also have a memory leak.
您还存在内存泄漏。
Try this instead:
试试这个:
#include <vcclr.h>
// 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);
If this works and the above doesn't, then something is wrong with the string sent from C#:
如果这是可行的,上面没有,那么从c#发送的字符串有问题:
System::String^ string = gcnew System::String(L"C:\\Program Files\\Java\\jre7\\bin\\Server\\jvm.dll");
pin_ptr<const WCHAR> lib_name = PtrToStringChars(string);
HINSTANCE handle = LoadLibraryW(lib_name);
#1
3
There are better ways for getting a C-style string from a System::String^
. Have a look at the marshal_as
and marshal_context
templates supplied with VC++.
有更好的方式获得c风格的字符串从一个系统:^:字符串。看看vc++提供的marshal_as和marshal_context模板。
Your immediate problem here is that you are compiling for Unicode, so LoadLibrary
requires a unicode string, but StringToHGlobalAnsi
does not return a unicode string. No amount of pointer casting will change the encoding of the string pointed to.
这里的直接问题是要编译Unicode,因此LoadLibrary需要一个Unicode字符串,但是StringToHGlobalAnsi不返回Unicode字符串。任何数量的指针转换都不会改变指向的字符串的编码。
You also have a memory leak.
您还存在内存泄漏。
Try this instead:
试试这个:
#include <vcclr.h>
// 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);
If this works and the above doesn't, then something is wrong with the string sent from C#:
如果这是可行的,上面没有,那么从c#发送的字符串有问题:
System::String^ string = gcnew System::String(L"C:\\Program Files\\Java\\jre7\\bin\\Server\\jvm.dll");
pin_ptr<const WCHAR> lib_name = PtrToStringChars(string);
HINSTANCE handle = LoadLibraryW(lib_name);