我有一个调用C dll的c#程序,后者又调用
java dll(使用jet excelsior构建第三方程序).我将一个xml字符串从c#传递到java中,然后java将字符串返回到c#进行处理.
这适用于第一次迭代,但是在第二次迭代时我得到以下异常……
Attempted to read or write protected memory. This is often an
indication that other memory is corrupt.
以下是我将其列为相关代码,但如果您需要其他任何内容,请告诉我.
C#调用C dll
public static class DllCall { [DllImport("Stubs",CallingConvention = CallingConvention.Cdecl)] public static extern int initDll([MarshalAs(UnmanagedType.LPStr)] string userDllName); [DllImport("Stubs",CallingConvention = CallingConvention.Cdecl)] public static extern void finalizeDll(); [DllImport("Stubs",CallingConvention = CallingConvention.Cdecl)] public static extern UInt32 newClassInstance(String rootPath,String cfgPath,String logPath ); [DllImport("Stubs",CallingConvention = CallingConvention.Cdecl)] public static extern String request(UInt32 hClassInst,[MarshalAs(UnmanagedType.LPStr)] String input); [DllImport("Stubs",CallingConvention = CallingConvention.Cdecl)] public static extern void close(); }
const char* request(jobject obj,char* input ) { jstring inputString; jstring outputString; const char *nativeString; jmethodID mID = (*env)->getmethodID (env,jClass,"request","(Ljava/lang/String;)Ljava/lang/String;"); if (!mID){ printf("\nError: dllClass.request() not found\n"); return 0; } inputString = (*env)->NewStringUTF(env,input); outputString = (*env)->CallObjectMethod(env,obj,mID,inputString); nativeString = (*env)->GetStringUTFChars(env,outputString,0); return nativeString; }
这里要求的是实际导致异常的C#代码.
public string request(string xmlInput) { LogManager.logMessage("Sending request to Java. Request is - " + xmlInput); string rs =""; Console.Write("Making request"); //this works fine rs = DllCall.request(hClass,xmlInput); Console.Write("---> request() rs = {0}\n",rs); // this throws the error rs = DllCall.request(hClass,"<?xml version='1.0' encoding='utf-8'?><moo><request name=\"Panel.Open.GetSelectionTemplate\"/></moo>"); return rs; }
在回应丹尼尔这里是宣告env的地方
#include <jni.h> #include <windows.h> jnienv *env; JavaVM *jvm; HANDLE hUserDll; jclass jClass; char* dllname;
以下是它的初始化方式.
int initDll(char* userDllName) { jClass = NULL; hUserDll = loadDll(userDllName); dllname = userDllName; initJavaRT(hUserDll,&jvm,&env); jClass = lookForClass(env,"XActMain/XActgeminiX3/XActgeminiX3IFX"); return jClass ? 1 : 0; } /* * Initialize JET run-time. */ void initJavaRT(HANDLE myDllHandle,JavaVM** pjvm,jnienv** penv) { int result; JavaVMInitArgs args; JNI_GetDefaultJavaVMInitArgs_func = (jint (JNICALL *) (void *args)) GetProcAddress (myDllHandle,"JNI_GetDefaultJavaVMInitArgs"); JNI_CreateJavaVM_func = (jint (JNICALL *) (JavaVM **pvm,void **penv,void *args)) GetProcAddress (myDllHandle,"JNI_CreateJavaVM"); if(!JNI_GetDefaultJavaVMInitArgs_func) { printf ("%s doesn't contain public JNI_GetDefaultJavaVMInitArgs\n",dllname); exit (1); } if(!JNI_CreateJavaVM_func) { printf ("%s doesn't contain public JNI_CreateJavaVM\n",dllname); exit (1); } memset (&args,sizeof(args)); args.version = JNI_VERSION_1_2; result = JNI_GetDefaultJavaVMInitArgs_func(&args); if (result != JNI_OK) { printf ("JNI_GetDefaultJavaVMInitArgs() Failed with result %d\n",result); exit(1); } /* * NOTE: no JVM is actually created * this call to JNI_CreateJavaVM is intended for JET RT initialization */ result = JNI_CreateJavaVM_func (pjvm,(void **)penv,&args); if (result != JNI_OK) { printf ("JNI_CreateJavaVM() Failed with result %d\n",result); exit(1); } printf ("JET RT initialized\n"); fflush (stdout); }
这是对Joes关于初始化的评论的回应……
public class Test { public UInt32 hClass; public test() { initDll(); newClassInstance(rootConfig,config,logFile); } ........ public void newClassInstance(string rootPath,string cfgPath,string logPath) { hClass = DllCall.newClassInstance(rootPath,cfgPath,logPath); Console.Write("---> hClass = {0}\n",hClass); } public void initDll() { int rc = DllCall.initDll("dllClass.dll"); Console.Write("---> initDll() rc = {0}\n",rc); }
汉斯指出了以下链接potential answer
正如我所说,它工作一次然后在第二次迭代时崩溃.
解决方法
我不确定它为什么第一次工作,但是你将一个类对象(hClass)传递给请求而不是该类的实例.
rs = DllCall.request(hClass,xmlInput); //The error is thrown on this line
看看这是否解决了问题:
public string request(string xmlInput) { LogManager.logMessage("Sending request to Java. Request is - " + xmlInput); string rs =""; Console.Write("Making request"); UInt32 hClassInst = DllCall.newClassInstance(rootPath,logPath); // <-- New line,using your own rootPath,logPath variables rs = DllCall.request(hClassInst,xmlInput); // <-- Modified line,using hClassInst instead of hClass Console.Write("---> request() rs = {0}\n",rs); return rs; }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。