通过JNI从Java调用C#方法触发StackOverflowException求助
Java调用C# DLL触发StackOverflowException问题
问题概述
我需要通过Java调用C#的许可证检查逻辑,该逻辑封装在一个包含public static string GetLicenseStatus()方法的C# DLL中,采用JNI+C++包装器实现跨语言调用。使用环境为64位Eclipse Adoptium jdk-17.0.2.8-hotspot、IntelliJ IDEA、Visual Studio 2022。
预期Java调用后返回代表许可证状态的字符串(0-4对应无效、有效、过期等),但执行C#代码时触发StackOverflowException。
已尝试操作
- 仅在C方法中返回固定值,不调用C#代码,JNI与C包装器交互正常;
- 单独运行C#代码,功能正常,排除C#代码本身问题;
- 自行编写简易测试C# DLL(仅校验模拟账号密码),即使仅返回true,从Java调用时仍触发StackOverflowException,错误出现在使用
gcnew实例化对象时。
额外说明:C#许可证DLL疑似依赖其他DLL;Visual Studio无法自动识别导入的头文件,需手动创建并复制代码。
相关代码
Authenticator.java
package org.example; public class Authenticator { static { System.loadLibrary("CppAuthenticator"); } public native boolean authenticate(String username, String password); public native String getLicenseStatus(); public static void main(String[] args) { System.out.println("Program start"); Authenticator authenticator = new Authenticator(); System.out.println("Authenticator created"); /**boolean valid = authenticator.authenticate(args[0], args[1]); System.out.println("Is valid?: "+valid); if(!valid) { System.err.println("Not valid!"); System.exit(1); } else { System.out.println("Valid"); }**/ System.out.println("License Check..."); System.out.println("Status: "+authenticator.getLicenseStatus()); } }
CppAuthenticator.cpp
#include "pch.h" #include <msclr\marshal.h> #include "CppAuthenticator.h" #include "org_example_Authenticator.h" // this is the main DLL file. #include <string> using System::Text::Encoding; String^ toString(const char* chars) { int len = (int)strlen(chars); array<unsigned char>^ a = gcnew array<unsigned char> (len); int i = 0; while (i < len) { a[i] = chars[i]; } return Encoding::UTF8->GetString(a); } bool authenticate(const char* username, const char* password) { SharpAuthenticator::Authenticator^ a = gcnew SharpAuthenticator::Authenticator(); // Fails here return a->Authenticate(toString(username), toString(password)); } JNIEXPORT jboolean JNICALL Java_org_example_Authenticator_authenticate (JNIEnv* env, jobject c, jstring username, jstring password) { jboolean isCopyUsername; const char *c_username = env->GetStringUTFChars(username, &isCopyUsername); jboolean isCopyPassword; const char* c_password = env->GetStringUTFChars(password, &isCopyPassword); jboolean result = authenticate(c_username, c_password); env->ReleaseStringUTFChars(username, c_username); env->ReleaseStringUTFChars(password, c_password); return result; } String^ getLicenseStatus() { return LicenseCheck::ValidateLicense::GetLicenseStatus(); // Fails here } JNIEXPORT jstring JNICALL Java_org_example_Authenticator_getLicenseStatus (JNIEnv* env, jobject c) { String^ cliString = getLicenseStatus(); msclr::interop::marshal_context context; const char* utf8String = context.marshal_as<const char*>(cliString); jstring result = env->NewStringUTF(utf8String); return result; }
SharpAuthenticator.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SharpAuthenticator { public class Authenticator { public bool Authenticate(String username, String password) { return username == "user" && password == "pass"; } public bool Authenticate1() { return false; } } }
项目相关截图
- Visual Studio项目结构:

- C++项目属性:

- 测试C# DLL项目属性:

内容的提问来源于stack exchange,提问作者Felix D
相关产品推荐
相关产品推荐

