尝试传入用户提供的字符串,该字符串具有jvm.dll的路径,但除非我使用以下代码进行硬编码,否则它不会加载库:
#define RUNTIME_DLL _T("C:\\Program Files\\Java\\jre7\\bin\\Server\\jvm.dll")
如果我尝试这个,它会编译但失败:
HINSTANCE handle = LoadLibrary((const char*)Marshal::StringToHGlobalAnsi(string).ToPointer());
“string”var具有_T()具有但仍然失败的精确复制和粘贴路径。不是C / C ++的专家,所以我不确定_T()是什么让它起作用。
更新
试过这个:
// 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);
仍然不会加载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);
也尝试过这个:
// 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
C ++ / CLI方法签名是:
void Initialize(String^ jvmDllPath)
正文基本上是上面的代码
使用字符串参数调用此代码的C#代码为:
obj.Initialize("c:\\program files\\java\\jdk7\\jre\\bin\\server\\jvm.dll");
根据Ben的建议在这里提供答案,以便人们/新手和临时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;
}
答案 0 :(得分:3)
有更好的方法可以从System::String^
获取C风格的字符串。查看VC ++提供的marshal_as
和marshal_context
模板。
这里您当前的问题是您正在编译Unicode,因此LoadLibrary
需要unicode字符串,但StringToHGlobalAnsi
不返回unicode字符串。没有多少指针转换会改变指向的字符串的编码。
你也有内存泄漏。
请改为尝试:
#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);
如果这样做而且上面没有,那么从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);