java - 从 Java 应用程序调用 C# 库:由于 StackOverflowException 而终止进程
问题描述
我有一个简单的 C# 类库,我将它包装在一个 C++/CLI 类库中并将其加载到一个简单的 Java 控制台应用程序中。但是当我运行 Java 应用程序时,我收到以下错误:
Process is terminated due to StackOverflowException.
Process finished with exit code -1073741571 (0xC00000FD)
我的 C# 库有一个 Class1.cs 文件:
using System;
namespace CSharpClassLibrary1
{
public class Class1
{
public Class1() { }
public void Print()
{
Console.WriteLine("Hello World From C#!");
}
}
}
我的 C++/CLI 包装器有两个文件:HelloWorld.h 和 CppClassLibrary1.cpp。
你好世界.h:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: print
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_print
(JNIEnv*, jobject);
#ifdef __cplusplus
}
#endif
#endif
我通过在我的 Java 应用程序中运行以下形式的命令得到它:javac -h <directory> -d <directory> <source files>
.
CppClassLibrary1.cpp:
#include "pch.h"
#include "HelloWorld.h"
using namespace CSharpClassLibrary1;
JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv* env, jobject obj)
{
Class1^ cls = gcnew Class1();
cls->Print();
}
我添加了 CSharpClassLibrary1 作为对 C++/CLI 包装器的引用。
我添加到“包含目录”设置以下路径:
C:\Users\ns16\AppData\Local\JetBrains\Toolbox\apps\IDEA-C\ch-0\192.6817.14\jbr\include
C:\Users\ns16\AppData\Local\JetBrains\Toolbox\apps\IDEA-C\ch-0\192.6817.14\jbr\include\win32
我的 Java 应用程序有一个 HelloWorld.java 文件:
public class HelloWorld {
public native void print();
static {
try {
System.loadLibrary("CppClassLibrary1");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load.\n" + e);
}
}
public static void main(String[] args) {
HelloWorld hw = new HelloWorld();
hw.print();
}
}
我在 java.library.path 变量中指定了 CppClassLibrary1 库路径。
请帮我!我究竟做错了什么?
更新。对该问题的研究表明:
在 Java 应用程序中出现错误的
hw.print();
行。如果您将其注释掉,应用程序将成功启动。如果在 CppClassLibrary1.cpp 文件中的 C++/CLI 包装器中将
Java_HelloWorld_print
函数主体替换为std::cout << "Hello World From C++/CLI!";
行,Java 应用程序将成功启动并打印Hello World From C++/CLI!
字符串。如果您创建 C# 控制台应用程序,将 C# 库作为引用添加到其中,并将代码添加到
Main
方法中Class1 cls = new Class1(); cls.print();
,应用程序将成功启动并打印Hello World From C#!
字符串。
解决方案
我将 C# 库程序集复制到带有 java.exe 文件的目录中(在我的系统中它位于C:\Users\ns16\AppData\Local\JetBrains\Toolbox\apps\IDEA-C\ch-0\192.6817.14\jbr\bin
),现在 Java 应用程序可以工作了!我不想将程序集移出项目目录,但这是我找到的唯一解决方案。
推荐阅读
- swiftui - 由于 iPad 设备的未捕获异常“NSGenericException”而终止应用程序
- rust - 递归引用包装
- python - 1 或 0 基于另一列中的值?[Python]
- css - React Navbar 中的徽标不会与链接对齐
- php - PHP 7 中用于 PKCS 1.5 RSA 加密的库
- java - 为什么 hasNext() 永远不会在 Scanner 类中结束?我想使用 Scanner 类输入一系列字符串
- wso2is - 通过文件将服务提供者添加到 WSO2 身份服务器不起作用
- epsg - adehabitatHR 家庭范围估计太小
- layout - 散景布局调整多个图的大小
- python - 从 URL PDF 文件中查找和提取特定文本,无需下载或写入(解决方案)