Reputation: 117
I'm working on building a Java wrapper around a C# project. I'm using C++ to go in between Java and 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." 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. I created a C++ test class, external to the wrapper C++ code, to try out the call and everything works fine from there. The C# dll load and runs as expected. So I'm guessing it's a problem with my Java project set up but I can't seem to find it.
I tried using Process Monitor to make sure that the C# dll isn't loading and it isn't. The c++ wrapper does load correctly.
My Java code is executing from the project folder but everything else (C++ and C#) are in the same directory. Any help is appreciated.
Java Code:
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):
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)
#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)
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;
}
Upvotes: 2
Views: 774
Reputation: 6050
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.
So resolve this problem, there're two way:
Put your C# DLL and its dependencies at the same folder of java.exe
Sign your C# DLL and make it strong name, then install it to GAC
To find out how java.exe search for the DLL, use the tool procmon from Microsoft
Upvotes: 3