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调用拉出到先前的初始化方法. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
