简体   繁体   English

通过JNI将Java转换为C#无法加载C#dll

[英]Java to C# through JNI fails to load C# dll

I'm working on building a Java wrapper around a C# project. 我正在围绕C#项目构建Java包装器。 I'm using C++ to go in between Java and C#. 我正在使用C ++在Java和C#之间切换。 My problem is that when I run my Java app I'm getting a "Could not load file or assembly 'MyC#DLL, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified." 我的问题是,当我运行Java应用程序时,出现“无法加载文件或程序集'MyC#DLL,版本= 1.0.0.0,文化=中性,公共密钥令牌=空”或其依赖项之一。系统无法找到指定的文件。” error. 错误。 If I remove the call in C++ to the C# code things load fine, as far as the Java to C++ part, but when I try to make the call to C# that dll fails to load. 如果我从C ++中删除对C#代码的调用,那么就可以很好地加载Java到C ++部分的东西,但是当我尝试对C#进行调用时,dll无法加载。 I created a C++ test class, external to the wrapper C++ code, to try out the call and everything works fine from there. 我在包装C ++代码外部创建了一个C ++测试类,以尝试调用,然后一切正常。 The C# dll load and runs as expected. C#dll加载并按预期运行。 So I'm guessing it's a problem with my Java project set up but I can't seem to find it. 因此,我猜测这是我的Java项目设置存在的问题,但我似乎找不到它。

I tried using Process Monitor to make sure that the C# dll isn't loading and it isn't. 我尝试使用Process Monitor来确保C#dll没有加载并且没有加载。 The c++ wrapper does load correctly. C ++包装程序确实可以正确加载。

My Java code is executing from the project folder but everything else (C++ and C#) are in the same directory. 我的Java代码是从项目文件夹执行的,但其他所有代码(C ++和C#)都位于同一目录中。 Any help is appreciated. 任何帮助表示赞赏。

Java Code: Java代码:

public final class MyClass{

static {
    try
    {
        System.load("C:\\Dir\\CppBridge.dll");
    }
    catch(Exception e)
    {
        System.out.println("-!-!- Error loading library -!-!-");
    }

}

private static native String getXML();

public static List<Site> getXMLFromC#()
{
    String xml = MyClass.getXML();
}}

C++ Code (Methods.h): C ++代码(Methods.h):

public ref class Wrapper
{
    public: MyPackage::C#Project^ api;
    public: Wrapper()
    {
        api = gcnew MyPackage::C#Project;
    }

    public: char* getXML()
    {
        char* error;
        try
        {
            System::String^ xml = api->getXML();
            return (char*)Marshal::StringToHGlobalAnsi(xml).ToPointer();
        }
        catch (Exception^ e)
        {
            char* error = (char*)Marshal::StringToHGlobalAnsi("Error:" + e->Message).ToPointer();
        }
        return error;
    }
};

C++ Code (CppBridge.h) C ++代码(CppBridge.h)

#include <jni.h>
/* Header for class MyC#Class*/

#ifndef _Included_MyC#Class
#define _Included_MyC#Class
#ifdef __cplusplus
extern "C" {
#endif
    /*
    * Class:     MyC#Class
    * Method:    getUserSites
    * Signature: String, String, String, String, String, boolean
    */
    JNIEXPORT jstring JNICALL Java_MyPackage_getXML(JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

C++ Code (CppBridge.cpp) C ++代码(CppBridge.cpp)

using namespace System::Runtime::InteropServices; //Marshal

class CppBridge
{
    public: CppBridge() {};
};

JNIEXPORT jstring JNICALL Java_MyPackage_getXML(JNIEnv *jn, jobject jobj)
{
    jstring error;
    try
    {
        Methods::Wrapper^ wrapper = gcnew Methods::Wrapper();
        char* xml = wrapper->getXML();
        jstring result = jn->NewStringUTF(xml);
        return result;
    }
    catch (Exception^ e)
    {
        char* result = (char*)Marshal::StringToHGlobalAnsi("Source: "+ e->Source + " | Message: " + e->Message).ToPointer();
        error = jn->NewStringUTF(result);
    }
    return error;
}

I encountered the same problem a year ago, the reason is simple: java.exe can't not find the C# DLL as java.exe only searches for the C# DLL in the same folder of java.exe and system GAC. 一年前,我遇到了同样的问题,原因很简单:java.exe找不到C#DLL,因为java.exe仅在java.exe和系统GAC的同一文件夹中搜索C#DLL。

So resolve this problem, there're two way: 因此,解决此问题有两种方法:

  1. Put your C# DLL and its dependencies at the same folder of java.exe 将您的C#DLL及其依赖项放在java.exe的同一文件夹中

  2. Sign your C# DLL and make it strong name, then install it to GAC 对您的C#DLL签名并使其具有强名,然后将其安装到GAC

To find out how java.exe search for the DLL, use the tool procmon from Microsoft 要了解java.exe如何搜索DLL,请使用Microsoft的procmon工具

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM