You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用JNA调用C#时出现java.lang.Error: Invalid memory access错误求助

Java通过JNA调用C#程序时触发java.lang.Error: Invalid memory access错误

错误信息

java.lang.Error: Invalid memory access

相关代码(64位环境)

C#代码

namespace EwpDeleteBlank
{
    public static class RemoveBlankPage
    {
    }
}

C++头文件(pch.h)

#ifndef PCH_H
#define PCH_H

#include "framework.h"
#include <string>

using namespace std;

#define  MYLIBAPI  extern "C" __declspec(dllexport) 

MYLIBAPI  void deleteBlankPages();

#endif //PCH_H

C++实现文件(pch.cpp)

#include "pch.h"
#include <string>

#using "C:\\Users\\zhang\\Desktop\\g\\ewp-delete-blank\\bin\\x64\\Debug\\RemoveBlankPage.dll"

using namespace EwpDeleteBlank;
using namespace std;

void deleteBlankPages() {
    RemoveBlankPage ^obj = gcnew RemoveBlankPage();
}

Java代码

public interface MyLibraryInterface extends Library {
    MyLibraryInterface instance = (MyLibraryInterface) Native.loadLibrary("Dll1.dll", MyLibraryInterface.class);
    void deleteBlankPages();
}

// 调用代码
MyLibraryInterface.instance.deleteBlankPages();

问题原因

  1. 托管与非托管兼容性冲突:你的C代码使用了#using托管DLL、gcnew等CLR特性,编译出的Dll1.dll是托管C DLL,而JNA仅支持调用纯原生非托管C/C++ DLL,两者的内存模型、调用约定完全不同,直接调用必然触发内存访问错误。
  2. C#静态类实例化错误:RemoveBlankPage是C#静态类,静态类不允许被实例化,gcnew RemoveBlankPage()本身就是非法操作,会触发CLR内部异常,进而传递给JNA导致内存访问报错。

解决方案

方案1:直接导出C#方法供JNA调用(推荐)

借助UnmanagedExports NuGet包,直接将C#方法导出为原生函数,无需C++中间层:

  1. 在C#项目中安装UnmanagedExports NuGet包。
  2. 修改C#代码:
namespace EwpDeleteBlank
{
    public class RemoveBlankPage
    {
        [DllExport("deleteBlankPages", CallingConvention = CallingConvention.Cdecl)]
        public static void DeleteBlankPages()
        {
            // 编写业务逻辑
        }
    }
}
  1. 编译生成64位C# DLL,Java端直接用JNA调用该DLL即可。

方案2:用COM方式实现C++与C#交互

如果必须保留C++中间层,需通过COM接口调用C#:

  1. 给C#类添加[ComVisible(true)]属性,在项目属性中勾选“为COM互操作注册”,将C#类注册为COM组件。
  2. 在C++代码中通过COM接口调用C#方法,编译为纯原生非托管DLL。
  3. Java端用JNA调用这个原生DLL。

方案3:修正基础代码错误(不推荐)

如果坚持使用C++/CLR中间层:

  1. 将C#的静态类改为普通类:
namespace EwpDeleteBlank
{
    public class RemoveBlankPage
    {
    }
}
  1. 确保C++项目编译为支持CLR的DLL,同时保证Java与DLL的架构一致(均为64位)。但这种方式本质仍为托管DLL,JNA调用仍可能存在兼容性问题。

内容的提问来源于stack exchange,提问作者marlon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 00:43:21