c# – 访问冲突异常
发布时间:2020-12-15 21:28:45 所属栏目:百科 来源:网络整理
导读:我有一个调用C dll的c#程序,后者又调用 java dll(使用jet excelsior构建第三方程序).我将一个xml字符串从c#传递到java中,然后java将字符串返回到c#进行处理. 这适用于第一次迭代,但是在第二次迭代时我得到以下异常…… Attempted to read or write protected
我有一个调用C dll的c#程序,后者又调用
java dll(使用jet excelsior构建第三方程序).我将一个xml字符串从c#传递到java中,然后java将字符串返回到c#进行处理.
这适用于第一次迭代,但是在第二次迭代时我得到以下异常……
以下是我将其列为相关代码,但如果您需要其他任何内容,请告诉我. 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(); } C dll中抛出错误的方法 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 foundn"); 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_GetDefaultJavaVMInitArgsn",dllname); exit (1); } if(!JNI_CreateJavaVM_func) { printf ("%s doesn't contain public JNI_CreateJavaVMn",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 %dn",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 %dn",result); exit(1); } printf ("JET RT initializedn"); 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; } 如果这可以解决问题,那么您应该重构它并将newClassInstance调用拉出到先前的初始化方法. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |